@@ -47,21 +47,164 @@ const struct pem_header_id pem_std_headers[] = {
4747};
4848const unsigned long pem_std_headers_num = sizeof (pem_std_headers )/sizeof (pem_std_headers [0 ]);
4949
50-
5150/* Encrypted PEM files */
5251const struct str pem_proc_type_encrypted = { SET_CSTR (, "Proc-Type: 4,ENCRYPTED" ) };
5352const struct str pem_dek_info_start = { SET_CSTR (, "DEK-Info: " ) };
54- const struct dek_info_from_str pem_dek_infos [] =
53+ const struct blockcipher_info pem_dek_infos [] =
5554 {
56- { SET_CSTR (.id , "AES-128-CBC," ), .info .alg = "aes" , .info .keylen = 128 / 8 , },
57- { SET_CSTR (.id , "AES-192-CBC," ), .info .alg = "aes" , .info .keylen = 192 / 8 , },
58- { SET_CSTR (.id , "AES-256-CBC," ), .info .alg = "aes" , .info .keylen = 256 / 8 , },
59- { SET_CSTR (.id , "CAMELLIA-128-CBC," ), .info .alg = "camellia" , .info .keylen = 128 / 8 , },
60- { SET_CSTR (.id , "CAMELLIA-192-CBC," ), .info .alg = "camellia" , .info .keylen = 192 / 8 , },
61- { SET_CSTR (.id , "CAMELLIA-256-CBC," ), .info .alg = "camellia" , .info .keylen = 256 / 8 , },
62- { SET_CSTR (.id , "DES-EDE3-CBC," ), .info .alg = "3des" , .info .keylen = 192 / 8 , },
63- { SET_CSTR (.id , "DES-CBC," ), .info .alg = "des" , .info .keylen = 64 / 8 , },
55+ { .name = "AES-128-CBC," , .algo = "aes" , .keylen = 128 / 8 , .mode = cm_cbc , },
56+ { .name = "AES-192-CBC," , .algo = "aes" , .keylen = 192 / 8 , .mode = cm_cbc , },
57+ { .name = "AES-256-CBC," , .algo = "aes" , .keylen = 256 / 8 , .mode = cm_cbc , },
58+ { .name = "AES-128-CFB," , .algo = "aes" , .keylen = 128 / 8 , .mode = cm_cfb , },
59+ { .name = "AES-192-CFB," , .algo = "aes" , .keylen = 192 / 8 , .mode = cm_cfb , },
60+ { .name = "AES-256-CFB," , .algo = "aes" , .keylen = 256 / 8 , .mode = cm_cfb , },
61+ { .name = "AES-128-CTR," , .algo = "aes" , .keylen = 128 / 8 , .mode = cm_ctr , },
62+ { .name = "AES-192-CTR," , .algo = "aes" , .keylen = 192 / 8 , .mode = cm_ctr , },
63+ { .name = "AES-256-CTR," , .algo = "aes" , .keylen = 256 / 8 , .mode = cm_ctr , },
64+ { .name = "AES-128-OFB," , .algo = "aes" , .keylen = 128 / 8 , .mode = cm_ofb , },
65+ { .name = "AES-192-OFB," , .algo = "aes" , .keylen = 192 / 8 , .mode = cm_ofb , },
66+ { .name = "AES-256-OFB," , .algo = "aes" , .keylen = 256 / 8 , .mode = cm_ofb , },
67+ { .name = "BF-CBC," , .algo = "blowfish" , .keylen = 128 / 8 , .mode = cm_cbc , },
68+ { .name = "BF-CFB," , .algo = "blowfish" , .keylen = 128 / 8 , .mode = cm_cfb , },
69+ { .name = "BF-OFB," , .algo = "blowfish" , .keylen = 128 / 8 , .mode = cm_ofb , },
70+ { .name = "CAMELLIA-128-CBC," , .algo = "camellia" , .keylen = 128 / 8 , .mode = cm_cbc , },
71+ { .name = "CAMELLIA-192-CBC," , .algo = "camellia" , .keylen = 192 / 8 , .mode = cm_cbc , },
72+ { .name = "CAMELLIA-256-CBC," , .algo = "camellia" , .keylen = 256 / 8 , .mode = cm_cbc , },
73+ { .name = "CAMELLIA-128-CFB," , .algo = "camellia" , .keylen = 128 / 8 , .mode = cm_cfb , },
74+ { .name = "CAMELLIA-192-CFB," , .algo = "camellia" , .keylen = 192 / 8 , .mode = cm_cfb , },
75+ { .name = "CAMELLIA-256-CFB," , .algo = "camellia" , .keylen = 256 / 8 , .mode = cm_cfb , },
76+ { .name = "CAMELLIA-128-CTR," , .algo = "camellia" , .keylen = 128 / 8 , .mode = cm_ctr , },
77+ { .name = "CAMELLIA-192-CTR," , .algo = "camellia" , .keylen = 192 / 8 , .mode = cm_ctr , },
78+ { .name = "CAMELLIA-256-CTR," , .algo = "camellia" , .keylen = 256 / 8 , .mode = cm_ctr , },
79+ { .name = "CAMELLIA-128-OFB," , .algo = "camellia" , .keylen = 128 / 8 , .mode = cm_ofb , },
80+ { .name = "CAMELLIA-192-OFB," , .algo = "camellia" , .keylen = 192 / 8 , .mode = cm_ofb , },
81+ { .name = "CAMELLIA-256-OFB," , .algo = "camellia" , .keylen = 256 / 8 , .mode = cm_ofb , },
82+ { .name = "CAST5-CBC," , .algo = "cast5" , .keylen = 128 / 8 , .mode = cm_cbc , },
83+ { .name = "CAST5-CFB," , .algo = "cast5" , .keylen = 128 / 8 , .mode = cm_cfb , },
84+ { .name = "CAST5-OFB," , .algo = "cast5" , .keylen = 128 / 8 , .mode = cm_ofb , },
85+ { .name = "DES-EDE3-CBC," , .algo = "3des" , .keylen = 192 / 8 , .mode = cm_cbc , },
86+ { .name = "DES-EDE3-CFB," , .algo = "3des" , .keylen = 192 / 8 , .mode = cm_cfb , },
87+ { .name = "DES-EDE3-OFB," , .algo = "3des" , .keylen = 192 / 8 , .mode = cm_ofb , },
88+ { .name = "DES-CBC," , .algo = "des" , .keylen = 64 / 8 , .mode = cm_cbc , },
89+ { .name = "DES-CFB," , .algo = "des" , .keylen = 64 / 8 , .mode = cm_cfb , },
90+ { .name = "DES-OFB," , .algo = "des" , .keylen = 64 / 8 , .mode = cm_ofb , },
91+ { .name = "IDEA-CBC," , .algo = "idea" , .keylen = 128 / 8 , .mode = cm_cbc , },
92+ { .name = "IDEA-CFB," , .algo = "idea" , .keylen = 128 / 8 , .mode = cm_cfb , },
93+ { .name = "IDEA-OFB," , .algo = "idea" , .keylen = 128 / 8 , .mode = cm_ofb , },
94+ { .name = "RC2-40-CBC," , .algo = "rc2" , .keylen = 40 / 8 , .mode = cm_cbc , },
95+ { .name = "RC2-64-CBC," , .algo = "rc2" , .keylen = 64 / 8 , .mode = cm_cbc , },
96+ { .name = "RC2-CBC," , .algo = "rc2" , .keylen = 128 / 8 , .mode = cm_cbc , },
97+ { .name = "RC2-CFB," , .algo = "rc2" , .keylen = 128 / 8 , .mode = cm_cfb , },
98+ { .name = "RC2-OFB," , .algo = "rc2" , .keylen = 128 / 8 , .mode = cm_ofb , },
99+ { .name = "SEED-CBC," , .algo = "seed" , .keylen = 128 / 8 , .mode = cm_cbc , },
100+ { .name = "SEED-CFB," , .algo = "seed" , .keylen = 128 / 8 , .mode = cm_cfb , },
101+ { .name = "SEED-OFB," , .algo = "seed" , .keylen = 128 / 8 , .mode = cm_ofb , },
64102 };
65103const unsigned long pem_dek_infos_num = sizeof (pem_dek_infos )/sizeof (pem_dek_infos [0 ]);
66104
105+ int pem_decrypt (unsigned char * data , unsigned long * datalen ,
106+ unsigned char * key , unsigned long keylen ,
107+ unsigned char * iv , unsigned long ivlen ,
108+ const struct blockcipher_info * info ,
109+ enum padding_type padding )
110+ {
111+ int err , cipher ;
112+ struct {
113+ union {
114+ #ifdef LTC_CBC_MODE
115+ symmetric_CBC cbc ;
116+ #endif
117+ #ifdef LTC_CFB_MODE
118+ symmetric_CFB cfb ;
119+ #endif
120+ #ifdef LTC_CTR_MODE
121+ symmetric_CTR ctr ;
122+ #endif
123+ #ifdef LTC_OFB_MODE
124+ symmetric_OFB ofb ;
125+ #endif
126+ } ctx ;
127+ } s ;
128+
129+ cipher = find_cipher (info -> algo );
130+ if (cipher == -1 ) {
131+ return CRYPT_INVALID_CIPHER ;
132+ }
133+
134+ switch (info -> mode ) {
135+ case cm_cbc :
136+ #ifdef LTC_CBC_MODE
137+ LTC_ARGCHK (ivlen == (unsigned long )cipher_descriptor [cipher ].block_length );
138+
139+ if ((err = cbc_start (cipher , iv , key , keylen , 0 , & s .ctx .cbc )) != CRYPT_OK ) {
140+ goto error_out ;
141+ }
142+ if ((err = cbc_decrypt (data , data , * datalen , & s .ctx .cbc )) != CRYPT_OK ) {
143+ goto error_out ;
144+ }
145+ if ((err = cbc_done (& s .ctx .cbc )) != CRYPT_OK ) {
146+ goto error_out ;
147+ }
148+
149+ if ((err = padding_depad (data , datalen , padding | s .ctx .cbc .blocklen )) != CRYPT_OK ) {
150+ goto error_out ;
151+ }
152+ #else
153+ return CRYPT_INVALID_CIPHER ;
154+ #endif
155+ break ;
156+ case cm_cfb :
157+ #ifdef LTC_CFB_MODE
158+ if ((err = cfb_start (cipher , iv , key , keylen , 0 , & s .ctx .cfb )) != CRYPT_OK ) {
159+ goto error_out ;
160+ }
161+ if ((err = cfb_decrypt (data , data , * datalen , & s .ctx .cfb )) != CRYPT_OK ) {
162+ goto error_out ;
163+ }
164+ if ((err = cfb_done (& s .ctx .cfb )) != CRYPT_OK ) {
165+ goto error_out ;
166+ }
167+ #else
168+ return CRYPT_INVALID_CIPHER ;
169+ #endif
170+ break ;
171+ case cm_ctr :
172+ #ifdef LTC_CTR_MODE
173+ if ((err = ctr_start (cipher , iv , key , keylen , 0 , CTR_COUNTER_BIG_ENDIAN , & s .ctx .ctr )) != CRYPT_OK ) {
174+ goto error_out ;
175+ }
176+ if ((err = ctr_decrypt (data , data , * datalen , & s .ctx .ctr )) != CRYPT_OK ) {
177+ goto error_out ;
178+ }
179+ if ((err = ctr_done (& s .ctx .ctr )) != CRYPT_OK ) {
180+ goto error_out ;
181+ }
182+ #else
183+ return CRYPT_INVALID_CIPHER ;
184+ #endif
185+ break ;
186+ case cm_ofb :
187+ #ifdef LTC_OFB_MODE
188+ if ((err = ofb_start (cipher , iv , key , keylen , 0 , & s .ctx .ofb )) != CRYPT_OK ) {
189+ goto error_out ;
190+ }
191+ if ((err = ofb_decrypt (data , data , * datalen , & s .ctx .ofb )) != CRYPT_OK ) {
192+ goto error_out ;
193+ }
194+ if ((err = ofb_done (& s .ctx .ofb )) != CRYPT_OK ) {
195+ goto error_out ;
196+ }
197+ #else
198+ return CRYPT_INVALID_CIPHER ;
199+ #endif
200+ break ;
201+ default :
202+ err = CRYPT_INVALID_ARG ;
203+ break ;
204+ }
205+
206+ error_out :
207+ return err ;
208+ }
209+
67210#endif /* LTC_PEM */
0 commit comments