xmldsign 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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