xmldsign 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.idea/.name +1 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/encodings.xml +5 -0
- data/.idea/misc.xml +25 -0
- data/.idea/modules.xml +9 -0
- data/.idea/scopes/scope_settings.xml +5 -0
- data/.idea/vcs.xml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/ext/xmldsign/extconf.rb +3 -0
- data/ext/xmldsign/gost89.c +409 -0
- data/ext/xmldsign/gost89.h +96 -0
- data/ext/xmldsign/gosthash.c +254 -0
- data/ext/xmldsign/gosthash.h +48 -0
- data/ext/xmldsign/xmldsign_ext.bundle +0 -0
- data/ext/xmldsign/xmldsign_ext.c +66 -0
- data/ext/xmldsign/xmldsign_ext.h +18 -0
- data/lib/xmldsign/algorithms.rb +84 -0
- data/lib/xmldsign/digests/gost.rb +30 -0
- data/lib/xmldsign/document.rb +19 -0
- data/lib/xmldsign/error.rb +2 -0
- data/lib/xmldsign/signature.rb +64 -0
- data/lib/xmldsign/signed_info.rb +7 -0
- data/lib/xmldsign/transforms.rb +17 -0
- data/lib/xmldsign/version.rb +3 -0
- data/lib/xmldsign.rb +21 -0
- data/spec/assets/act-birth-for-sign.xml +118 -0
- data/spec/assets/act-birth-with-comment-for-sign.xml +105 -0
- data/spec/assets/act-death-for-sign.xml +75 -0
- data/spec/assets/act-death-with-empty-tags-for-sign.xml +75 -0
- data/spec/assets/csr.pem +11 -0
- data/spec/assets/private.key.pem +15 -0
- data/spec/assets/private.passw.key.pem +18 -0
- data/spec/assets/public.key.pem +6 -0
- data/spec/assets/signed-act-birth-with-comment.xml +134 -0
- data/spec/assets/signed-act-birth.xml +116 -0
- data/spec/assets/signed-act-changed-ns-order.xml +137 -0
- data/spec/assets/signed-act-changed-prefixes.xml +136 -0
- data/spec/assets/signed-act-changed-xml-comments.xml +146 -0
- data/spec/assets/signed-act-death-with-empty-tags.xml +117 -0
- data/spec/assets/signed-act-death.xml +117 -0
- data/spec/assets/signed-act-wrong-canon-alg.xml +34 -0
- data/spec/assets/signed-act-wrong-data.xml +133 -0
- data/spec/assets/signed-act-wrong-sign-alg.xml +34 -0
- data/spec/assets/signed-act-wrong-signature-value.xml +133 -0
- data/spec/assets/signed-act-wrong-trans-alg.xml +34 -0
- data/spec/assets/signed-act-wrong-trans-algs-order.xml +34 -0
- data/spec/assets/signed-act-wrong-trans-count.xml +31 -0
- data/spec/assets/signed-act-wrong-trans0-alg.xml +34 -0
- data/spec/assets/signed-act-wrong-transxslt-alg.xml +34 -0
- data/spec/assets/signed-info-for-act-birth.xml +15 -0
- data/spec/assets/signed.test.xml +103 -0
- data/spec/assets/unsigned.test.xml +14 -0
- data/spec/assets/x509.crt +13 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/xmldsign/sign_spec.rb +24 -0
- data/xmldsign.gemspec +29 -0
- metadata +254 -0
data/.gitignore
ADDED
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>
|
data/.idea/encodings.xml
ADDED
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
|
+
|
data/.idea/vcs.xml
ADDED
data/Gemfile
ADDED
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,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
|