xmldsign 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/.gitignore +18 -0
  2. data/.idea/.name +1 -0
  3. data/.idea/.rakeTasks +7 -0
  4. data/.idea/encodings.xml +5 -0
  5. data/.idea/misc.xml +25 -0
  6. data/.idea/modules.xml +9 -0
  7. data/.idea/scopes/scope_settings.xml +5 -0
  8. data/.idea/vcs.xml +7 -0
  9. data/Gemfile +4 -0
  10. data/LICENSE.txt +22 -0
  11. data/README.md +29 -0
  12. data/Rakefile +1 -0
  13. data/ext/xmldsign/extconf.rb +3 -0
  14. data/ext/xmldsign/gost89.c +409 -0
  15. data/ext/xmldsign/gost89.h +96 -0
  16. data/ext/xmldsign/gosthash.c +254 -0
  17. data/ext/xmldsign/gosthash.h +48 -0
  18. data/ext/xmldsign/xmldsign_ext.bundle +0 -0
  19. data/ext/xmldsign/xmldsign_ext.c +66 -0
  20. data/ext/xmldsign/xmldsign_ext.h +18 -0
  21. data/lib/xmldsign/algorithms.rb +84 -0
  22. data/lib/xmldsign/digests/gost.rb +30 -0
  23. data/lib/xmldsign/document.rb +19 -0
  24. data/lib/xmldsign/error.rb +2 -0
  25. data/lib/xmldsign/signature.rb +64 -0
  26. data/lib/xmldsign/signed_info.rb +7 -0
  27. data/lib/xmldsign/transforms.rb +17 -0
  28. data/lib/xmldsign/version.rb +3 -0
  29. data/lib/xmldsign.rb +21 -0
  30. data/spec/assets/act-birth-for-sign.xml +118 -0
  31. data/spec/assets/act-birth-with-comment-for-sign.xml +105 -0
  32. data/spec/assets/act-death-for-sign.xml +75 -0
  33. data/spec/assets/act-death-with-empty-tags-for-sign.xml +75 -0
  34. data/spec/assets/csr.pem +11 -0
  35. data/spec/assets/private.key.pem +15 -0
  36. data/spec/assets/private.passw.key.pem +18 -0
  37. data/spec/assets/public.key.pem +6 -0
  38. data/spec/assets/signed-act-birth-with-comment.xml +134 -0
  39. data/spec/assets/signed-act-birth.xml +116 -0
  40. data/spec/assets/signed-act-changed-ns-order.xml +137 -0
  41. data/spec/assets/signed-act-changed-prefixes.xml +136 -0
  42. data/spec/assets/signed-act-changed-xml-comments.xml +146 -0
  43. data/spec/assets/signed-act-death-with-empty-tags.xml +117 -0
  44. data/spec/assets/signed-act-death.xml +117 -0
  45. data/spec/assets/signed-act-wrong-canon-alg.xml +34 -0
  46. data/spec/assets/signed-act-wrong-data.xml +133 -0
  47. data/spec/assets/signed-act-wrong-sign-alg.xml +34 -0
  48. data/spec/assets/signed-act-wrong-signature-value.xml +133 -0
  49. data/spec/assets/signed-act-wrong-trans-alg.xml +34 -0
  50. data/spec/assets/signed-act-wrong-trans-algs-order.xml +34 -0
  51. data/spec/assets/signed-act-wrong-trans-count.xml +31 -0
  52. data/spec/assets/signed-act-wrong-trans0-alg.xml +34 -0
  53. data/spec/assets/signed-act-wrong-transxslt-alg.xml +34 -0
  54. data/spec/assets/signed-info-for-act-birth.xml +15 -0
  55. data/spec/assets/signed.test.xml +103 -0
  56. data/spec/assets/unsigned.test.xml +14 -0
  57. data/spec/assets/x509.crt +13 -0
  58. data/spec/spec_helper.rb +22 -0
  59. data/spec/xmldsign/sign_spec.rb +24 -0
  60. data/xmldsign.gemspec +29 -0
  61. metadata +254 -0
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ Makefile
data/.idea/.name ADDED
@@ -0,0 +1 @@
1
+ xmldsign
data/.idea/.rakeTasks ADDED
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Settings><!--This file was automatically generated by Ruby plugin.
3
+ You are allowed to:
4
+ 1. Remove rake task
5
+ 2. Add existing rake tasks
6
+ To add existing rake tasks automatically delete this file and reload the project.
7
+ --><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build xmldsign-0.0.1.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Build and install xmldsign-0.0.1.gem into system gems" fullCmd="install" taksId="install" /><RakeTask description="Create tag v0.0.1 and build and push xmldsign-0.0.1.gem to Rubygems" fullCmd="release" taksId="release" /></RakeGroup></Settings>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
4
+ </project>
5
+
data/.idea/misc.xml ADDED
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectResources">
4
+ <default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
5
+ </component>
6
+ <component name="ProjectRootManager" version="2" project-jdk-name="RVM: ruby-1.9.3-p194" project-jdk-type="RUBY_SDK" />
7
+ <component name="SvnConfiguration" maxAnnotateRevisions="500" myUseAcceleration="nothing" myAutoUpdateAfterCommit="false" cleanupOnStartRun="false">
8
+ <option name="USER" value="" />
9
+ <option name="PASSWORD" value="" />
10
+ <option name="mySSHConnectionTimeout" value="30000" />
11
+ <option name="mySSHReadTimeout" value="30000" />
12
+ <option name="LAST_MERGED_REVISION" />
13
+ <option name="MERGE_DRY_RUN" value="false" />
14
+ <option name="MERGE_DIFF_USE_ANCESTRY" value="true" />
15
+ <option name="UPDATE_LOCK_ON_DEMAND" value="false" />
16
+ <option name="IGNORE_SPACES_IN_MERGE" value="false" />
17
+ <option name="DETECT_NESTED_COPIES" value="true" />
18
+ <option name="CHECK_NESTED_FOR_QUICK_MERGE" value="false" />
19
+ <option name="IGNORE_SPACES_IN_ANNOTATE" value="true" />
20
+ <option name="SHOW_MERGE_SOURCES_IN_ANNOTATE" value="true" />
21
+ <option name="FORCE_UPDATE" value="false" />
22
+ <myIsUseDefaultProxy>false</myIsUseDefaultProxy>
23
+ </component>
24
+ </project>
25
+
data/.idea/modules.xml ADDED
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/xmldsign.iml" filepath="$PROJECT_DIR$/.idea/xmldsign.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
9
+
@@ -0,0 +1,5 @@
1
+ <component name="DependencyValidationManager">
2
+ <state>
3
+ <option name="SKIP_IMPORT_STATEMENTS" value="false" />
4
+ </state>
5
+ </component>
data/.idea/vcs.xml ADDED
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
7
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in xmldsign.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Anton Sozontov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Xmldsign
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'xmldsign'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install xmldsign
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile('xmldsign/xmldsign_ext')
@@ -0,0 +1,409 @@
1
+ /**********************************************************************
2
+ * gost89.c *
3
+ * Copyright (c) 2005-2006 Cryptocom LTD *
4
+ * This file is distributed under the same license as OpenSSL *
5
+ * *
6
+ * Implementation of GOST 28147-89 encryption algorithm *
7
+ * No OpenSSL libraries required to compile and use *
8
+ * this code *
9
+ **********************************************************************/
10
+ #include <string.h>
11
+ #include "gost89.h"
12
+ /* Substitution blocks from RFC 4357
13
+
14
+ Note: our implementation of gost 28147-89 algorithm
15
+ uses S-box matrix rotated 90 degrees counterclockwise, relative to
16
+ examples given in RFC.
17
+
18
+
19
+ */
20
+
21
+ /* Substitution blocks from test examples for GOST R 34.11-94*/
22
+ gost_subst_block GostR3411_94_TestParamSet = {
23
+ {0X1,0XF,0XD,0X0,0X5,0X7,0XA,0X4,0X9,0X2,0X3,0XE,0X6,0XB,0X8,0XC},
24
+ {0XD,0XB,0X4,0X1,0X3,0XF,0X5,0X9,0X0,0XA,0XE,0X7,0X6,0X8,0X2,0XC},
25
+ {0X4,0XB,0XA,0X0,0X7,0X2,0X1,0XD,0X3,0X6,0X8,0X5,0X9,0XC,0XF,0XE},
26
+ {0X6,0XC,0X7,0X1,0X5,0XF,0XD,0X8,0X4,0XA,0X9,0XE,0X0,0X3,0XB,0X2},
27
+ {0X7,0XD,0XA,0X1,0X0,0X8,0X9,0XF,0XE,0X4,0X6,0XC,0XB,0X2,0X5,0X3},
28
+ {0X5,0X8,0X1,0XD,0XA,0X3,0X4,0X2,0XE,0XF,0XC,0X7,0X6,0X0,0X9,0XB},
29
+ {0XE,0XB,0X4,0XC,0X6,0XD,0XF,0XA,0X2,0X3,0X8,0X1,0X0,0X7,0X5,0X9},
30
+ {0X4,0XA,0X9,0X2,0XD,0X8,0X0,0XE,0X6,0XB,0X1,0XC,0X7,0XF,0X5,0X3}
31
+ };
32
+ /* Substitution blocks for hash function 1.2.643.2.9.1.6.1 */
33
+ gost_subst_block GostR3411_94_CryptoProParamSet= {
34
+ {0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC},
35
+ {0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB},
36
+ {0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3},
37
+ {0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5},
38
+ {0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3},
39
+ {0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD},
40
+ {0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8},
41
+ {0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF}
42
+ } ;
43
+
44
+ /* Test paramset from GOST 28147 */
45
+ gost_subst_block Gost28147_TestParamSet =
46
+ {
47
+ {0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8},
48
+ {0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD},
49
+ {0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4},
50
+ {0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4},
51
+ {0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8},
52
+ {0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB},
53
+ {0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5},
54
+ {0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6}
55
+ };
56
+
57
+
58
+
59
+
60
+ /* 1.2.643.2.2.31.1 */
61
+ gost_subst_block Gost28147_CryptoProParamSetA= {
62
+ {0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4},
63
+ {0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE},
64
+ {0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6},
65
+ {0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6},
66
+ {0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6},
67
+ {0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9},
68
+ {0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1},
69
+ {0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5}
70
+ };
71
+ /* 1.2.643.2.2.31.2 */
72
+ gost_subst_block Gost28147_CryptoProParamSetB=
73
+ {
74
+ {0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC},
75
+ {0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE},
76
+ {0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5},
77
+ {0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3},
78
+ {0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8},
79
+ {0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4},
80
+ {0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE},
81
+ {0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF}
82
+ };
83
+ /* 1.2.643.2.2.31.3 */
84
+ gost_subst_block Gost28147_CryptoProParamSetC=
85
+ {
86
+ {0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8},
87
+ {0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7},
88
+ {0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD},
89
+ {0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7},
90
+ {0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4},
91
+ {0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB},
92
+ {0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3},
93
+ {0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3}
94
+ };
95
+
96
+ /* 1.2.643.2.2.31.4 */
97
+ gost_subst_block Gost28147_CryptoProParamSetD=
98
+ {
99
+ {0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE},
100
+ {0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7},
101
+ {0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6},
102
+ {0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1},
103
+ {0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8},
104
+ {0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2},
105
+ {0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1},
106
+ {0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3}
107
+ };
108
+
109
+
110
+ const byte CryptoProKeyMeshingKey[]={
111
+ 0x69, 0x00, 0x72, 0x22, 0x64, 0xC9, 0x04, 0x23,
112
+ 0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4,
113
+ 0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12,
114
+ 0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B
115
+ };
116
+ /* Initialization of gost_ctx subst blocks*/
117
+ static void kboxinit(gost_ctx *c, const gost_subst_block *b)
118
+ {
119
+ int i;
120
+
121
+ for (i = 0; i < 256; i++)
122
+ {
123
+ c->k87[i] = (b->k8[i>>4] <<4 | b->k7 [i &15])<<24;
124
+ c->k65[i] = (b->k6[i>>4] << 4 | b->k5 [i &15])<<16;
125
+ c->k43[i] = (b->k4[i>>4] <<4 | b->k3 [i &15])<<8;
126
+ c->k21[i] = b->k2[i>>4] <<4 | b->k1 [i &15];
127
+
128
+ }
129
+ }
130
+
131
+ /* Part of GOST 28147 algorithm moved into separate function */
132
+ static word32 f(gost_ctx *c,word32 x)
133
+ {
134
+ x = c->k87[x>>24 & 255] | c->k65[x>>16 & 255]|
135
+ c->k43[x>> 8 & 255] | c->k21[x & 255];
136
+ /* Rotate left 11 bits */
137
+ return x<<11 | x>>(32-11);
138
+ }
139
+ /* Low-level encryption routine - encrypts one 64 bit block*/
140
+ void gostcrypt(gost_ctx *c, const byte *in, byte *out)
141
+ {
142
+ register word32 n1, n2; /* As named in the GOST */
143
+ n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24);
144
+ n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24);
145
+ /* Instead of swapping halves, swap names each round */
146
+
147
+ n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
148
+ n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
149
+ n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
150
+ n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
151
+
152
+ n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
153
+ n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
154
+ n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
155
+ n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
156
+
157
+ n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
158
+ n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
159
+ n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
160
+ n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
161
+
162
+ n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
163
+ n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
164
+ n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
165
+ n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
166
+
167
+ out[0] = (byte)(n2&0xff); out[1] = (byte)((n2>>8)&0xff);
168
+ out[2] = (byte)((n2>>16)&0xff); out[3]=(byte)(n2>>24);
169
+ out[4] = (byte)(n1&0xff); out[5] = (byte)((n1>>8)&0xff);
170
+ out[6] = (byte)((n1>>16)&0xff); out[7] = (byte)(n1>>24);
171
+ }
172
+ /* Low-level decryption routine. Decrypts one 64-bit block */
173
+ void gostdecrypt(gost_ctx *c, const byte *in,byte *out)
174
+ {
175
+ register word32 n1, n2; /* As named in the GOST */
176
+ n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24);
177
+ n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24);
178
+
179
+ n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
180
+ n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
181
+ n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
182
+ n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
183
+
184
+ n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
185
+ n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
186
+ n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
187
+ n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
188
+
189
+ n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
190
+ n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
191
+ n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
192
+ n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
193
+
194
+ n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
195
+ n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
196
+ n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
197
+ n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
198
+
199
+ out[0] = (byte)(n2&0xff); out[1] = (byte)((n2>>8)&0xff);
200
+ out[2] = (byte)((n2>>16)&0xff); out[3]=(byte)(n2>>24);
201
+ out[4] = (byte)(n1&0xff); out[5] = (byte)((n1>>8)&0xff);
202
+ out[6] = (byte)((n1>>16)&0xff); out[7] = (byte)(n1>>24);
203
+ }
204
+
205
+ /* Encrypts several blocks in ECB mode */
206
+ void gost_enc(gost_ctx *c,const byte *clear,byte *cipher, int blocks)
207
+ {
208
+ int i;
209
+ for(i=0;i<blocks;i++)
210
+ {
211
+ gostcrypt(c,clear,cipher);
212
+ clear+=8;
213
+ cipher+=8;
214
+ }
215
+ }
216
+ /* Decrypts several blocks in ECB mode */
217
+ void gost_dec(gost_ctx *c, const byte *cipher,byte *clear, int blocks)
218
+ {
219
+ int i;
220
+ for(i=0;i<blocks;i++)
221
+ {
222
+ gostdecrypt(c,cipher,clear);
223
+ clear+=8;
224
+ cipher+=8;
225
+ }
226
+ }
227
+
228
+ /* Encrypts several full blocks in CFB mode using 8byte IV */
229
+ void gost_enc_cfb(gost_ctx *ctx,const byte *iv,const byte *clear,byte *cipher, int blocks)
230
+ {
231
+ byte cur_iv[8];
232
+ byte gamma[8];
233
+ int i,j;
234
+ const byte *in;
235
+ byte *out;
236
+ memcpy(cur_iv,iv,8);
237
+ for(i=0,in=clear,out=cipher;i<blocks;i++,in+=8,out+=8)
238
+ {
239
+ gostcrypt(ctx,cur_iv,gamma);
240
+ for (j=0;j<8;j++)
241
+ {
242
+ cur_iv[j]=out[j]=in[j]^gamma[j];
243
+ }
244
+ }
245
+ }
246
+ /* Decrypts several full blocks in CFB mode using 8byte IV */
247
+ void gost_dec_cfb(gost_ctx *ctx,const byte *iv,const byte *cipher,byte *clear, int blocks)
248
+ {
249
+ byte cur_iv[8];
250
+ byte gamma[8];
251
+ int i,j;
252
+ const byte *in;
253
+ byte *out;
254
+ memcpy(cur_iv,iv,8);
255
+ for(i=0,in=cipher,out=clear;i<blocks;i++,in+=8,out+=8)
256
+ {
257
+ gostcrypt(ctx,cur_iv,gamma);
258
+ for (j=0;j<8;j++)
259
+ {
260
+ out[j]=(cur_iv[j]=in[j])^gamma[j];
261
+ }
262
+ }
263
+ }
264
+
265
+ /* Encrypts one block using specified key */
266
+ void gost_enc_with_key(gost_ctx *c,byte *key,byte *inblock,byte *outblock)
267
+ {
268
+ gost_key(c,key);
269
+ gostcrypt(c,inblock,outblock);
270
+ }
271
+
272
+ /* Set 256 bit key into context */
273
+ void gost_key(gost_ctx *c, const byte *k)
274
+ {
275
+ int i,j;
276
+ for(i=0,j=0;i<8;i++,j+=4)
277
+ {
278
+ c->k[i]=k[j]|(k[j+1]<<8)|(k[j+2]<<16)|(k[j+3]<<24);
279
+ }
280
+ }
281
+
282
+ /* Retrieve 256-bit key from context */
283
+ void gost_get_key(gost_ctx *c, byte *k)
284
+ {
285
+ int i,j;
286
+ for(i=0,j=0;i<8;i++,j+=4)
287
+ {
288
+ k[j]=(byte)(c->k[i]& 0xFF);
289
+ k[j+1]=(byte)((c->k[i]>>8 )&0xFF);
290
+ k[j+2]=(byte)((c->k[i]>>16) &0xFF);
291
+ k[j+3]=(byte)((c->k[i]>>24) &0xFF);
292
+ }
293
+ }
294
+
295
+ /* Initalize context. Provides default value for subst_block */
296
+ void gost_init(gost_ctx *c, const gost_subst_block *b)
297
+ {
298
+ if(!b)
299
+ {
300
+ b=&GostR3411_94_TestParamSet;
301
+ }
302
+ kboxinit(c,b);
303
+ }
304
+
305
+ /* Cleans up key from context */
306
+ void gost_destroy(gost_ctx *c)
307
+ {
308
+ int i; for(i=0;i<8;i++) c->k[i]=0;
309
+ }
310
+
311
+ /* Compute GOST 28147 mac block
312
+ *
313
+ * Parameters
314
+ * gost_ctx *c - context initalized with substitution blocks and key
315
+ * buffer - 8-byte mac state buffer
316
+ * block 8-byte block to process.
317
+ * */
318
+ void mac_block(gost_ctx *c,byte *buffer,const byte *block)
319
+ {
320
+ register word32 n1, n2; /* As named in the GOST */
321
+ int i;
322
+ for (i=0; i<8; i++)
323
+ {
324
+ buffer[i]^=block[i];
325
+ }
326
+ n1 = buffer[0]|(buffer[1]<<8)|(buffer[2]<<16)|(buffer[3]<<24);
327
+ n2 = buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24);
328
+ /* Instead of swapping halves, swap names each round */
329
+
330
+ n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
331
+ n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
332
+ n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
333
+ n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
334
+
335
+ n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
336
+ n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
337
+ n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
338
+ n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
339
+
340
+ buffer[0] = (byte)(n1&0xff); buffer[1] = (byte)((n1>>8)&0xff);
341
+ buffer[2] = (byte)((n1>>16)&0xff); buffer[3] = (byte)(n1>>24);
342
+ buffer[4] = (byte)(n2&0xff); buffer[5] = (byte)((n2>>8)&0xff);
343
+ buffer[6] = (byte)((n2>>16)&0xff); buffer[7] = (byte)(n2>>24);
344
+ }
345
+
346
+ /* Get mac with specified number of bits from MAC state buffer */
347
+ void get_mac(byte *buffer,int nbits,byte *out)
348
+ {
349
+ int nbytes= nbits >> 3;
350
+ int rembits = nbits & 7;
351
+ int mask =rembits?((1<rembits)-1):0;
352
+ int i;
353
+ for (i=0;i<nbytes;i++) out[i]=buffer[i];
354
+ if (rembits) out[i]=buffer[i]&mask;
355
+ }
356
+
357
+ /* Compute mac of specified length (in bits) from data.
358
+ * Context should be initialized with key and subst blocks */
359
+ int gost_mac(gost_ctx *ctx,int mac_len,const unsigned char *data,
360
+ unsigned int data_len,unsigned char *mac)
361
+ {
362
+ byte buffer[8]={0,0,0,0,0,0,0,0};
363
+ byte buf2[8];
364
+ unsigned int i;
365
+ for (i=0;i+8<=data_len;i+=8)
366
+ mac_block(ctx,buffer,data+i);
367
+ if (i<data_len)
368
+ {
369
+ memset(buf2,0,8);
370
+ memcpy(buf2,data+i,data_len-i);
371
+ mac_block(ctx,buffer,buf2);
372
+ }
373
+ get_mac(buffer,mac_len,mac);
374
+ return 1;
375
+ }
376
+
377
+ /* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */
378
+ int gost_mac_iv(gost_ctx *ctx,int mac_len,const unsigned char *iv,const unsigned char *data,
379
+ unsigned int data_len,unsigned char *mac)
380
+ {
381
+ byte buffer[8];
382
+ byte buf2[8];
383
+ unsigned int i;
384
+ memcpy (buffer,iv,8);
385
+ for (i=0;i+8<=data_len;i+=8)
386
+ mac_block(ctx,buffer,data+i);
387
+ if (i<data_len)
388
+ {
389
+ memset(buf2,0,8);
390
+ memcpy(buf2,data+i,data_len-i);
391
+ mac_block(ctx,buffer,buf2);
392
+ }
393
+ get_mac(buffer,mac_len,mac);
394
+ return 1;
395
+ }
396
+
397
+ /* Implements key meshing algorithm by modifing ctx and IV in place */
398
+ void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv)
399
+ {
400
+ unsigned char newkey[32],newiv[8];
401
+ /* Set static keymeshing key */
402
+ /* "Decrypt" key with keymeshing key */
403
+ gost_dec(ctx,CryptoProKeyMeshingKey,newkey,4);
404
+ /* set new key */
405
+ gost_key(ctx,newkey);
406
+ /* Encrypt iv with new key */
407
+ gostcrypt(ctx,iv,newiv);
408
+ memcpy(iv,newiv,8);
409
+ }
@@ -0,0 +1,96 @@
1
+ /**********************************************************************
2
+ * gost89.h *
3
+ * Copyright (c) 2005-2006 Cryptocom LTD *
4
+ * This file is distributed under the same license as OpenSSL *
5
+ * *
6
+ * Declarations for GOST 28147-89 encryption algorithm *
7
+ * No OpenSSL libraries required to compile and use *
8
+ * this code *
9
+ **********************************************************************/
10
+ #ifndef GOST89_H
11
+ #define GOST89_H
12
+
13
+ /* Typedef for unsigned 32-bit integer */
14
+ #if __LONG_MAX__ > 2147483647L
15
+ typedef unsigned int u4;
16
+ #else
17
+ typedef unsigned long u4;
18
+ #endif
19
+ /* Typedef for unsigned 8-bit integer */
20
+ typedef unsigned char byte;
21
+
22
+ /* Internal representation of GOST substitution blocks */
23
+ typedef struct {
24
+ byte k8[16];
25
+ byte k7[16];
26
+ byte k6[16];
27
+ byte k5[16];
28
+ byte k4[16];
29
+ byte k3[16];
30
+ byte k2[16];
31
+ byte k1[16];
32
+ } gost_subst_block;
33
+
34
+
35
+ /* Cipher context includes key and preprocessed substitution block */
36
+ typedef struct {
37
+ u4 k[8];
38
+ /* Constant s-boxes -- set up in gost_init(). */
39
+ u4 k87[256],k65[256],k43[256],k21[256];
40
+ } gost_ctx;
41
+ /* Note: encrypt and decrypt expect full blocks--padding blocks is
42
+ caller's responsibility. All bulk encryption is done in
43
+ ECB mode by these calls. Other modes may be added easily
44
+ enough. */
45
+ /* Encrypt several full blocks in ECB mode */
46
+ void gost_enc(gost_ctx *ctx, const byte *clear,byte *cipher, int blocks);
47
+ /* Decrypt several full blocks in ECB mode */
48
+ void gost_dec(gost_ctx *ctx, const byte *cipher,byte *clear, int blocks);
49
+ /* Encrypts several full blocks in CFB mode using 8byte IV */
50
+ void gost_enc_cfb(gost_ctx *ctx,const byte *iv,const byte *clear,byte *cipher,int blocks);
51
+ /* Decrypts several full blocks in CFB mode using 8byte IV */
52
+ void gost_dec_cfb(gost_ctx *ctx,const byte *iv,const byte *cipher,byte *clear,int blocks);
53
+
54
+ /* Encrypt one block */
55
+ void gostcrypt(gost_ctx *c, const byte *in, byte *out);
56
+ /* Decrypt one block */
57
+ void gostdecrypt(gost_ctx *c, const byte *in,byte *out);
58
+ /* Set key into context */
59
+ void gost_key(gost_ctx *ctx, const byte *key);
60
+ /* Get key from context */
61
+ void gost_get_key(gost_ctx *ctx, byte *key);
62
+ /* Set S-blocks into context */
63
+ void gost_init(gost_ctx *ctx, const gost_subst_block *subst_block);
64
+ /* Clean up context */
65
+ void gost_destroy(gost_ctx *ctx);
66
+ /* Intermediate function used for calculate hash */
67
+ void gost_enc_with_key(gost_ctx *,byte *key,byte *inblock,byte *outblock);
68
+ /* Compute MAC of given length in bits from data */
69
+ int gost_mac(gost_ctx *ctx,int hmac_len,const unsigned char *data,
70
+ unsigned int data_len,unsigned char *hmac) ;
71
+ /* Compute MAC of given length in bits from data, using non-zero 8-byte
72
+ * IV (non-standard, for use in CryptoPro key transport only */
73
+ int gost_mac_iv(gost_ctx *ctx,int hmac_len,const unsigned char *iv,const unsigned char *data,
74
+ unsigned int data_len,unsigned char *hmac) ;
75
+ /* Perform one step of MAC calculation like gostcrypt */
76
+ void mac_block(gost_ctx *c,byte *buffer,const byte *block);
77
+ /* Extracts MAC value from mac state buffer */
78
+ void get_mac(byte *buffer,int nbits,byte *out);
79
+ /* Implements cryptopro key meshing algorithm. Expect IV to be 8-byte size*/
80
+ void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv);
81
+ /* Parameter sets specified in RFC 4357 */
82
+ extern gost_subst_block GostR3411_94_TestParamSet;
83
+ extern gost_subst_block GostR3411_94_CryptoProParamSet;
84
+ extern gost_subst_block Gost28147_TestParamSet;
85
+ extern gost_subst_block Gost28147_CryptoProParamSetA;
86
+ extern gost_subst_block Gost28147_CryptoProParamSetB;
87
+ extern gost_subst_block Gost28147_CryptoProParamSetC;
88
+ extern gost_subst_block Gost28147_CryptoProParamSetD;
89
+ extern const byte CryptoProKeyMeshingKey[];
90
+ #if __LONG_MAX__ > 2147483647L
91
+ typedef unsigned int word32;
92
+ #else
93
+ typedef unsigned long word32;
94
+ #endif
95
+
96
+ #endif