used rsa coeff field in OpenPGP secret key payload
[strongswan.git] / src / libstrongswan / plugins / padlock / padlock_plugin.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "padlock_plugin.h"
17 #include "padlock_aes_crypter.h"
18 #include "padlock_sha1_hasher.h"
19 #include "padlock_rng.h"
20
21 #include <stdio.h>
22
23 #include <library.h>
24 #include <debug.h>
25
26 typedef struct private_padlock_plugin_t private_padlock_plugin_t;
27 typedef enum padlock_feature_t padlock_feature_t;
28
29 /**
30 * Feature flags of padlock, received via cpuid()
31 */
32 enum padlock_feature_t {
33 PADLOCK_RESERVED_1 = (1<<0),
34 PADLOCK_RESERVED_2 = (1<<1),
35 PADLOCK_RNG_AVAILABLE = (1<<2),
36 PADLOCK_RNG_ENABLED = (1<<3),
37 PADLOCK_RESERVED_3 = (1<<4),
38 PADLOCK_RESERVED_4 = (1<<5),
39 PADLOCK_ACE_AVAILABLE = (1<<6),
40 PADLOCK_ACE_ENABLED = (1<<7),
41 PADLOCK_ACE2_AVAILABLE = (1<<8),
42 PADLOCK_ACE2_ENABLED = (1<<9),
43 PADLOCK_PHE_AVAILABLE = (1<<10),
44 PADLOCK_PHE_ENABLED = (1<<11),
45 PADLOCK_PMM_AVAILABLE = (1<<12),
46 PADLOCK_PMM_ENABLED = (1<<13),
47 };
48
49 /**
50 * private data of aes_plugin
51 */
52 struct private_padlock_plugin_t {
53
54 /**
55 * public functions
56 */
57 padlock_plugin_t public;
58
59 /**
60 * features supported by Padlock
61 */
62 padlock_feature_t features;
63 };
64
65 /**
66 * Get cpuid for info, return eax, ebx, ecx and edx. -fPIC requires to save ebx.
67 */
68 #define cpuid(op, a, b, c, d)\
69 asm (\
70 "pushl %%ebx \n\t"\
71 "cpuid \n\t"\
72 "movl %%ebx, %1 \n\t"\
73 "popl %%ebx \n\t"\
74 : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
75 : "a" (op));
76
77 /**
78 * Get features supported by Padlock
79 */
80 static padlock_feature_t get_padlock_features()
81 {
82 char vendor[3 * sizeof(int) + 1];
83 int a, b, c, d;
84
85 cpuid(0, a, b, c, d);
86 /* VendorID string is in b-d-c (yes, in this order) */
87 snprintf(vendor, sizeof(vendor), "%.4s%.4s%.4s", &b, &d, &c);
88
89 /* check if we have a VIA chip */
90 if (streq(vendor, "CentaurHauls"))
91 {
92 cpuid(0xC0000000, a, b, c, d);
93 /* check Centaur Extended Feature Flags */
94 if (a >= 0xC0000001)
95 {
96 cpuid(0xC0000001, a, b, c, d);
97 return d;
98 }
99 }
100 DBG1("Padlock not found, CPU is %s\n", vendor);
101 return 0;
102 }
103
104 /**
105 * Implementation of aes_plugin_t.destroy
106 */
107 static void destroy(private_padlock_plugin_t *this)
108 {
109 if (this->features & PADLOCK_RNG_ENABLED)
110 {
111 lib->crypto->remove_rng(lib->crypto,
112 (rng_constructor_t)padlock_rng_create);
113 lib->crypto->remove_rng(lib->crypto,
114 (rng_constructor_t)padlock_rng_create);
115 lib->crypto->remove_rng(lib->crypto,
116 (rng_constructor_t)padlock_rng_create);
117 }
118 if (this->features & PADLOCK_ACE2_ENABLED)
119 {
120 lib->crypto->remove_crypter(lib->crypto,
121 (crypter_constructor_t)padlock_aes_crypter_create);
122 }
123 if (this->features & PADLOCK_PHE_ENABLED)
124 {
125 lib->crypto->remove_hasher(lib->crypto,
126 (hasher_constructor_t)padlock_sha1_hasher_create);
127 }
128 free(this);
129 }
130
131 /*
132 * see header file
133 */
134 plugin_t *plugin_create()
135 {
136 private_padlock_plugin_t *this = malloc_thing(private_padlock_plugin_t);
137
138 this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
139
140 this->features = get_padlock_features();
141 if (!this->features)
142 {
143 free(this);
144 return NULL;
145 }
146 DBG1("Padlock found, supports:%s%s%s%s%s, enabled:%s%s%s%s%s",
147 this->features & PADLOCK_RNG_AVAILABLE ? " RNG" : "",
148 this->features & PADLOCK_ACE_AVAILABLE ? " ACE" : "",
149 this->features & PADLOCK_ACE2_AVAILABLE ? " ACE2" : "",
150 this->features & PADLOCK_PHE_AVAILABLE ? " PHE" : "",
151 this->features & PADLOCK_PMM_AVAILABLE ? " PMM" : "",
152 this->features & PADLOCK_RNG_ENABLED ? " RNG" : "",
153 this->features & PADLOCK_ACE_ENABLED ? " ACE" : "",
154 this->features & PADLOCK_ACE2_ENABLED ? " ACE2" : "",
155 this->features & PADLOCK_PHE_ENABLED ? " PHE" : "",
156 this->features & PADLOCK_PMM_ENABLED ? " PMM" : "");
157
158 if (this->features & PADLOCK_RNG_ENABLED)
159 {
160 lib->crypto->add_rng(lib->crypto, RNG_TRUE,
161 (rng_constructor_t)padlock_rng_create);
162 lib->crypto->add_rng(lib->crypto, RNG_STRONG,
163 (rng_constructor_t)padlock_rng_create);
164 lib->crypto->add_rng(lib->crypto, RNG_WEAK,
165 (rng_constructor_t)padlock_rng_create);
166 }
167 if (this->features & PADLOCK_ACE2_ENABLED)
168 {
169 lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
170 (crypter_constructor_t)padlock_aes_crypter_create);
171 }
172 if (this->features & PADLOCK_PHE_ENABLED)
173 {
174 lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
175 (hasher_constructor_t)padlock_sha1_hasher_create);
176 }
177 return &this->public.plugin;
178 }