Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/oscrypto/_openssl/symmetric.py: 12%

207 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:25 +0000

1# coding: utf-8 

2from __future__ import unicode_literals, division, absolute_import, print_function 

3 

4import math 

5 

6from .._errors import pretty_message 

7from .._ffi import new, null, is_null, buffer_from_bytes, bytes_from_buffer, deref 

8from ._libcrypto import libcrypto, libcrypto_legacy_support, LibcryptoConst, handle_openssl_error 

9from ..util import rand_bytes 

10from .._types import type_name, byte_cls 

11 

12 

13__all__ = [ 

14 'aes_cbc_no_padding_decrypt', 

15 'aes_cbc_no_padding_encrypt', 

16 'aes_cbc_pkcs7_decrypt', 

17 'aes_cbc_pkcs7_encrypt', 

18 'des_cbc_pkcs5_decrypt', 

19 'des_cbc_pkcs5_encrypt', 

20 'rc2_cbc_pkcs5_decrypt', 

21 'rc2_cbc_pkcs5_encrypt', 

22 'rc4_decrypt', 

23 'rc4_encrypt', 

24 'tripledes_cbc_pkcs5_decrypt', 

25 'tripledes_cbc_pkcs5_encrypt', 

26] 

27 

28 

29def aes_cbc_no_padding_encrypt(key, data, iv): 

30 """ 

31 Encrypts plaintext using AES in CBC mode with a 128, 192 or 256 bit key and 

32 no padding. This means the ciphertext must be an exact multiple of 16 bytes 

33 long. 

34 

35 :param key: 

36 The encryption key - a byte string either 16, 24 or 32 bytes long 

37 

38 :param data: 

39 The plaintext - a byte string 

40 

41 :param iv: 

42 The initialization vector - either a byte string 16-bytes long or None 

43 to generate an IV 

44 

45 :raises: 

46 ValueError - when any of the parameters contain an invalid value 

47 TypeError - when any of the parameters are of the wrong type 

48 OSError - when an error is returned by OpenSSL 

49 

50 :return: 

51 A tuple of two byte strings (iv, ciphertext) 

52 """ 

53 

54 cipher = _calculate_aes_cipher(key) 

55 

56 if not iv: 

57 iv = rand_bytes(16) 

58 elif len(iv) != 16: 

59 raise ValueError(pretty_message( 

60 ''' 

61 iv must be 16 bytes long - is %s 

62 ''', 

63 len(iv) 

64 )) 

65 

66 if len(data) % 16 != 0: 

67 raise ValueError(pretty_message( 

68 ''' 

69 data must be a multiple of 16 bytes long - is %s 

70 ''', 

71 len(data) 

72 )) 

73 

74 return (iv, _encrypt(cipher, key, data, iv, False)) 

75 

76 

77def aes_cbc_no_padding_decrypt(key, data, iv): 

78 """ 

79 Decrypts AES ciphertext in CBC mode using a 128, 192 or 256 bit key and no 

80 padding. 

81 

82 :param key: 

83 The encryption key - a byte string either 16, 24 or 32 bytes long 

84 

85 :param data: 

86 The ciphertext - a byte string 

87 

88 :param iv: 

89 The initialization vector - a byte string 16-bytes long 

90 

91 :raises: 

92 ValueError - when any of the parameters contain an invalid value 

93 TypeError - when any of the parameters are of the wrong type 

94 OSError - when an error is returned by OpenSSL 

95 

96 :return: 

97 A byte string of the plaintext 

98 """ 

99 

100 cipher = _calculate_aes_cipher(key) 

101 

102 if len(iv) != 16: 

103 raise ValueError(pretty_message( 

104 ''' 

105 iv must be 16 bytes long - is %s 

106 ''', 

107 len(iv) 

108 )) 

109 

110 return _decrypt(cipher, key, data, iv, False) 

111 

112 

113def aes_cbc_pkcs7_encrypt(key, data, iv): 

114 """ 

115 Encrypts plaintext using AES in CBC mode with a 128, 192 or 256 bit key and 

116 PKCS#7 padding. 

117 

118 :param key: 

119 The encryption key - a byte string either 16, 24 or 32 bytes long 

120 

121 :param data: 

122 The plaintext - a byte string 

123 

124 :param iv: 

125 The initialization vector - either a byte string 16-bytes long or None 

126 to generate an IV 

127 

128 :raises: 

129 ValueError - when any of the parameters contain an invalid value 

130 TypeError - when any of the parameters are of the wrong type 

131 OSError - when an error is returned by OpenSSL 

132 

133 :return: 

134 A tuple of two byte strings (iv, ciphertext) 

135 """ 

136 

137 cipher = _calculate_aes_cipher(key) 

138 

139 if not iv: 

140 iv = rand_bytes(16) 

141 elif len(iv) != 16: 

142 raise ValueError(pretty_message( 

143 ''' 

144 iv must be 16 bytes long - is %s 

145 ''', 

146 len(iv) 

147 )) 

148 

149 return (iv, _encrypt(cipher, key, data, iv, True)) 

150 

151 

152def aes_cbc_pkcs7_decrypt(key, data, iv): 

153 """ 

154 Decrypts AES ciphertext in CBC mode using a 128, 192 or 256 bit key 

155 

156 :param key: 

157 The encryption key - a byte string either 16, 24 or 32 bytes long 

158 

159 :param data: 

160 The ciphertext - a byte string 

161 

162 :param iv: 

163 The initialization vector - a byte string 16-bytes long 

164 

165 :raises: 

166 ValueError - when any of the parameters contain an invalid value 

167 TypeError - when any of the parameters are of the wrong type 

168 OSError - when an error is returned by OpenSSL 

169 

170 :return: 

171 A byte string of the plaintext 

172 """ 

173 

174 cipher = _calculate_aes_cipher(key) 

175 

176 if len(iv) != 16: 

177 raise ValueError(pretty_message( 

178 ''' 

179 iv must be 16 bytes long - is %s 

180 ''', 

181 len(iv) 

182 )) 

183 

184 return _decrypt(cipher, key, data, iv, True) 

185 

186 

187def _calculate_aes_cipher(key): 

188 """ 

189 Determines if the key is a valid AES 128, 192 or 256 key 

190 

191 :param key: 

192 A byte string of the key to use 

193 

194 :raises: 

195 ValueError - when an invalid key is provided 

196 

197 :return: 

198 A unicode string of the AES variation - "aes128", "aes192" or "aes256" 

199 """ 

200 

201 if len(key) not in [16, 24, 32]: 

202 raise ValueError(pretty_message( 

203 ''' 

204 key must be either 16, 24 or 32 bytes (128, 192 or 256 bits) 

205 long - is %s 

206 ''', 

207 len(key) 

208 )) 

209 

210 if len(key) == 16: 

211 cipher = 'aes128' 

212 elif len(key) == 24: 

213 cipher = 'aes192' 

214 elif len(key) == 32: 

215 cipher = 'aes256' 

216 

217 return cipher 

218 

219 

220def rc4_encrypt(key, data): 

221 """ 

222 Encrypts plaintext using RC4 with a 40-128 bit key 

223 

224 :param key: 

225 The encryption key - a byte string 5-16 bytes long 

226 

227 :param data: 

228 The plaintext - a byte string 

229 

230 :raises: 

231 ValueError - when any of the parameters contain an invalid value 

232 TypeError - when any of the parameters are of the wrong type 

233 OSError - when an error is returned by OpenSSL 

234 

235 :return: 

236 A byte string of the ciphertext 

237 """ 

238 

239 if not libcrypto_legacy_support: 

240 raise EnvironmentError('OpenSSL has been compiled without RC4 support') 

241 

242 if len(key) < 5 or len(key) > 16: 

243 raise ValueError(pretty_message( 

244 ''' 

245 key must be 5 to 16 bytes (40 to 128 bits) long - is %s 

246 ''', 

247 len(key) 

248 )) 

249 

250 return _encrypt('rc4', key, data, None, None) 

251 

252 

253def rc4_decrypt(key, data): 

254 """ 

255 Decrypts RC4 ciphertext using a 40-128 bit key 

256 

257 :param key: 

258 The encryption key - a byte string 5-16 bytes long 

259 

260 :param data: 

261 The ciphertext - a byte string 

262 

263 :raises: 

264 ValueError - when any of the parameters contain an invalid value 

265 TypeError - when any of the parameters are of the wrong type 

266 OSError - when an error is returned by OpenSSL 

267 

268 :return: 

269 A byte string of the plaintext 

270 """ 

271 

272 if not libcrypto_legacy_support: 

273 raise EnvironmentError('OpenSSL has been compiled without RC4 support') 

274 

275 if len(key) < 5 or len(key) > 16: 

276 raise ValueError(pretty_message( 

277 ''' 

278 key must be 5 to 16 bytes (40 to 128 bits) long - is %s 

279 ''', 

280 len(key) 

281 )) 

282 

283 return _decrypt('rc4', key, data, None, None) 

284 

285 

286def rc2_cbc_pkcs5_encrypt(key, data, iv): 

287 """ 

288 Encrypts plaintext using RC2 in CBC mode with a 40-128 bit key and PKCS#5 

289 padding. 

290 

291 :param key: 

292 The encryption key - a byte string 8 bytes long 

293 

294 :param data: 

295 The plaintext - a byte string 

296 

297 :param iv: 

298 The initialization vector - a byte string 8-bytes long or None 

299 to generate an IV 

300 

301 :raises: 

302 ValueError - when any of the parameters contain an invalid value 

303 TypeError - when any of the parameters are of the wrong type 

304 OSError - when an error is returned by OpenSSL 

305 

306 :return: 

307 A tuple of two byte strings (iv, ciphertext) 

308 """ 

309 

310 if not libcrypto_legacy_support: 

311 raise EnvironmentError('OpenSSL has been compiled without RC2 support') 

312 

313 if len(key) < 5 or len(key) > 16: 

314 raise ValueError(pretty_message( 

315 ''' 

316 key must be 5 to 16 bytes (40 to 128 bits) long - is %s 

317 ''', 

318 len(key) 

319 )) 

320 

321 if not iv: 

322 iv = rand_bytes(8) 

323 elif len(iv) != 8: 

324 raise ValueError(pretty_message( 

325 ''' 

326 iv must be 8 bytes long - is %s 

327 ''', 

328 len(iv) 

329 )) 

330 

331 return (iv, _encrypt('rc2', key, data, iv, True)) 

332 

333 

334def rc2_cbc_pkcs5_decrypt(key, data, iv): 

335 """ 

336 Decrypts RC2 ciphertext ib CBC mode using a 40-128 bit key and PKCS#5 

337 padding. 

338 

339 :param key: 

340 The encryption key - a byte string 8 bytes long 

341 

342 :param data: 

343 The ciphertext - a byte string 

344 

345 :param iv: 

346 The initialization vector - a byte string 8 bytes long 

347 

348 :raises: 

349 ValueError - when any of the parameters contain an invalid value 

350 TypeError - when any of the parameters are of the wrong type 

351 OSError - when an error is returned by OpenSSL 

352 

353 :return: 

354 A byte string of the plaintext 

355 """ 

356 

357 if not libcrypto_legacy_support: 

358 raise EnvironmentError('OpenSSL has been compiled without RC2 support') 

359 

360 if len(key) < 5 or len(key) > 16: 

361 raise ValueError(pretty_message( 

362 ''' 

363 key must be 5 to 16 bytes (40 to 128 bits) long - is %s 

364 ''', 

365 len(key) 

366 )) 

367 

368 if len(iv) != 8: 

369 raise ValueError(pretty_message( 

370 ''' 

371 iv must be 8 bytes long - is %s 

372 ''', 

373 len(iv) 

374 )) 

375 

376 return _decrypt('rc2', key, data, iv, True) 

377 

378 

379def tripledes_cbc_pkcs5_encrypt(key, data, iv): 

380 """ 

381 Encrypts plaintext using 3DES in CBC mode using either the 2 or 3 key 

382 variant (16 or 24 byte long key) and PKCS#5 padding. 

383 

384 :param key: 

385 The encryption key - a byte string 16 or 24 bytes long (2 or 3 key mode) 

386 

387 :param data: 

388 The plaintext - a byte string 

389 

390 :param iv: 

391 The initialization vector - a byte string 8-bytes long or None 

392 to generate an IV 

393 

394 :raises: 

395 ValueError - when any of the parameters contain an invalid value 

396 TypeError - when any of the parameters are of the wrong type 

397 OSError - when an error is returned by OpenSSL 

398 

399 :return: 

400 A tuple of two byte strings (iv, ciphertext) 

401 """ 

402 

403 if len(key) != 16 and len(key) != 24: 

404 raise ValueError(pretty_message( 

405 ''' 

406 key must be 16 bytes (2 key) or 24 bytes (3 key) long - %s 

407 ''', 

408 len(key) 

409 )) 

410 

411 if not iv: 

412 iv = rand_bytes(8) 

413 elif len(iv) != 8: 

414 raise ValueError(pretty_message( 

415 ''' 

416 iv must be 8 bytes long - %s 

417 ''', 

418 len(iv) 

419 )) 

420 

421 cipher = 'tripledes_3key' 

422 # Expand 2-key to actual 24 byte byte string used by cipher 

423 if len(key) == 16: 

424 key = key + key[0:8] 

425 cipher = 'tripledes_2key' 

426 

427 return (iv, _encrypt(cipher, key, data, iv, True)) 

428 

429 

430def tripledes_cbc_pkcs5_decrypt(key, data, iv): 

431 """ 

432 Decrypts 3DES ciphertext in CBC mode using either the 2 or 3 key variant 

433 (16 or 24 byte long key) and PKCS#5 padding. 

434 

435 :param key: 

436 The encryption key - a byte string 16 or 24 bytes long (2 or 3 key mode) 

437 

438 :param data: 

439 The ciphertext - a byte string 

440 

441 :param iv: 

442 The initialization vector - a byte string 8-bytes long 

443 

444 :raises: 

445 ValueError - when any of the parameters contain an invalid value 

446 TypeError - when any of the parameters are of the wrong type 

447 OSError - when an error is returned by OpenSSL 

448 

449 :return: 

450 A byte string of the plaintext 

451 """ 

452 

453 if len(key) != 16 and len(key) != 24: 

454 raise ValueError(pretty_message( 

455 ''' 

456 key must be 16 bytes (2 key) or 24 bytes (3 key) long - is %s 

457 ''', 

458 len(key) 

459 )) 

460 

461 if len(iv) != 8: 

462 raise ValueError(pretty_message( 

463 ''' 

464 iv must be 8 bytes long - is %s 

465 ''', 

466 len(iv) 

467 )) 

468 

469 cipher = 'tripledes_3key' 

470 # Expand 2-key to actual 24 byte byte string used by cipher 

471 if len(key) == 16: 

472 key = key + key[0:8] 

473 cipher = 'tripledes_2key' 

474 

475 return _decrypt(cipher, key, data, iv, True) 

476 

477 

478def des_cbc_pkcs5_encrypt(key, data, iv): 

479 """ 

480 Encrypts plaintext using DES in CBC mode with a 56 bit key and PKCS#5 

481 padding. 

482 

483 :param key: 

484 The encryption key - a byte string 8 bytes long (includes error correction bits) 

485 

486 :param data: 

487 The plaintext - a byte string 

488 

489 :param iv: 

490 The initialization vector - a byte string 8-bytes long or None 

491 to generate an IV 

492 

493 :raises: 

494 ValueError - when any of the parameters contain an invalid value 

495 TypeError - when any of the parameters are of the wrong type 

496 OSError - when an error is returned by OpenSSL 

497 

498 :return: 

499 A tuple of two byte strings (iv, ciphertext) 

500 """ 

501 

502 if not libcrypto_legacy_support: 

503 raise EnvironmentError('OpenSSL has been compiled without DES support') 

504 

505 if len(key) != 8: 

506 raise ValueError(pretty_message( 

507 ''' 

508 key must be 8 bytes (56 bits + 8 parity bits) long - is %s 

509 ''', 

510 len(key) 

511 )) 

512 

513 if not iv: 

514 iv = rand_bytes(8) 

515 elif len(iv) != 8: 

516 raise ValueError(pretty_message( 

517 ''' 

518 iv must be 8 bytes long - is %s 

519 ''', 

520 len(iv) 

521 )) 

522 

523 return (iv, _encrypt('des', key, data, iv, True)) 

524 

525 

526def des_cbc_pkcs5_decrypt(key, data, iv): 

527 """ 

528 Decrypts DES ciphertext in CBC mode using a 56 bit key and PKCS#5 padding. 

529 

530 :param key: 

531 The encryption key - a byte string 8 bytes long (includes error correction bits) 

532 

533 :param data: 

534 The ciphertext - a byte string 

535 

536 :param iv: 

537 The initialization vector - a byte string 8-bytes long 

538 

539 :raises: 

540 ValueError - when any of the parameters contain an invalid value 

541 TypeError - when any of the parameters are of the wrong type 

542 OSError - when an error is returned by OpenSSL 

543 

544 :return: 

545 A byte string of the plaintext 

546 """ 

547 

548 if not libcrypto_legacy_support: 

549 raise EnvironmentError('OpenSSL has been compiled without DES support') 

550 

551 if len(key) != 8: 

552 raise ValueError(pretty_message( 

553 ''' 

554 key must be 8 bytes (56 bits + 8 parity bits) long - is %s 

555 ''', 

556 len(key) 

557 )) 

558 

559 if len(iv) != 8: 

560 raise ValueError(pretty_message( 

561 ''' 

562 iv must be 8 bytes long - is %s 

563 ''', 

564 len(iv) 

565 )) 

566 

567 return _decrypt('des', key, data, iv, True) 

568 

569 

570def _encrypt(cipher, key, data, iv, padding): 

571 """ 

572 Encrypts plaintext 

573 

574 :param cipher: 

575 A unicode string of "aes128", "aes192", "aes256", "des", 

576 "tripledes_2key", "tripledes_3key", "rc2", "rc4" 

577 

578 :param key: 

579 The encryption key - a byte string 5-32 bytes long 

580 

581 :param data: 

582 The plaintext - a byte string 

583 

584 :param iv: 

585 The initialization vector - a byte string - unused for RC4 

586 

587 :param padding: 

588 Boolean, if padding should be used - unused for RC4 

589 

590 :raises: 

591 ValueError - when any of the parameters contain an invalid value 

592 TypeError - when any of the parameters are of the wrong type 

593 OSError - when an error is returned by OpenSSL 

594 

595 :return: 

596 A byte string of the ciphertext 

597 """ 

598 

599 if not isinstance(key, byte_cls): 

600 raise TypeError(pretty_message( 

601 ''' 

602 key must be a byte string, not %s 

603 ''', 

604 type_name(key) 

605 )) 

606 

607 if not isinstance(data, byte_cls): 

608 raise TypeError(pretty_message( 

609 ''' 

610 data must be a byte string, not %s 

611 ''', 

612 type_name(data) 

613 )) 

614 

615 if cipher != 'rc4' and not isinstance(iv, byte_cls): 

616 raise TypeError(pretty_message( 

617 ''' 

618 iv must be a byte string, not %s 

619 ''', 

620 type_name(iv) 

621 )) 

622 

623 if cipher != 'rc4' and not padding: 

624 # AES in CBC mode can be allowed with no padding if 

625 # the data is an exact multiple of the block size 

626 is_aes = cipher in set(['aes128', 'aes192', 'aes256']) 

627 if not is_aes or (is_aes and (len(data) % 16) != 0): 

628 raise ValueError('padding must be specified') 

629 

630 evp_cipher_ctx = None 

631 

632 try: 

633 evp_cipher_ctx = libcrypto.EVP_CIPHER_CTX_new() 

634 if is_null(evp_cipher_ctx): 

635 handle_openssl_error(0) 

636 

637 evp_cipher, buffer_size = _setup_evp_encrypt_decrypt(cipher, data) 

638 

639 if iv is None: 

640 iv = null() 

641 

642 if cipher in set(['rc2', 'rc4']): 

643 res = libcrypto.EVP_EncryptInit_ex(evp_cipher_ctx, evp_cipher, null(), null(), null()) 

644 handle_openssl_error(res) 

645 res = libcrypto.EVP_CIPHER_CTX_set_key_length(evp_cipher_ctx, len(key)) 

646 handle_openssl_error(res) 

647 if cipher == 'rc2': 

648 res = libcrypto.EVP_CIPHER_CTX_ctrl( 

649 evp_cipher_ctx, 

650 LibcryptoConst.EVP_CTRL_SET_RC2_KEY_BITS, 

651 len(key) * 8, 

652 null() 

653 ) 

654 handle_openssl_error(res) 

655 evp_cipher = null() 

656 

657 res = libcrypto.EVP_EncryptInit_ex(evp_cipher_ctx, evp_cipher, null(), key, iv) 

658 handle_openssl_error(res) 

659 

660 if padding is not None: 

661 res = libcrypto.EVP_CIPHER_CTX_set_padding(evp_cipher_ctx, int(padding)) 

662 handle_openssl_error(res) 

663 

664 buffer = buffer_from_bytes(buffer_size) 

665 output_length = new(libcrypto, 'int *') 

666 

667 res = libcrypto.EVP_EncryptUpdate(evp_cipher_ctx, buffer, output_length, data, len(data)) 

668 handle_openssl_error(res) 

669 

670 output = bytes_from_buffer(buffer, deref(output_length)) 

671 

672 res = libcrypto.EVP_EncryptFinal_ex(evp_cipher_ctx, buffer, output_length) 

673 handle_openssl_error(res) 

674 

675 output += bytes_from_buffer(buffer, deref(output_length)) 

676 

677 return output 

678 

679 finally: 

680 if evp_cipher_ctx: 

681 libcrypto.EVP_CIPHER_CTX_free(evp_cipher_ctx) 

682 

683 

684def _decrypt(cipher, key, data, iv, padding): 

685 """ 

686 Decrypts AES/RC4/RC2/3DES/DES ciphertext 

687 

688 :param cipher: 

689 A unicode string of "aes128", "aes192", "aes256", "des", 

690 "tripledes_2key", "tripledes_3key", "rc2", "rc4" 

691 

692 :param key: 

693 The encryption key - a byte string 5-32 bytes long 

694 

695 :param data: 

696 The ciphertext - a byte string 

697 

698 :param iv: 

699 The initialization vector - a byte string - unused for RC4 

700 

701 :param padding: 

702 Boolean, if padding should be used - unused for RC4 

703 

704 :raises: 

705 ValueError - when any of the parameters contain an invalid value 

706 TypeError - when any of the parameters are of the wrong type 

707 OSError - when an error is returned by OpenSSL 

708 

709 :return: 

710 A byte string of the plaintext 

711 """ 

712 

713 if not isinstance(key, byte_cls): 

714 raise TypeError(pretty_message( 

715 ''' 

716 key must be a byte string, not %s 

717 ''', 

718 type_name(key) 

719 )) 

720 

721 if not isinstance(data, byte_cls): 

722 raise TypeError(pretty_message( 

723 ''' 

724 data must be a byte string, not %s 

725 ''', 

726 type_name(data) 

727 )) 

728 

729 if cipher != 'rc4' and not isinstance(iv, byte_cls): 

730 raise TypeError(pretty_message( 

731 ''' 

732 iv must be a byte string, not %s 

733 ''', 

734 type_name(iv) 

735 )) 

736 

737 if cipher not in set(['rc4', 'aes128', 'aes192', 'aes256']) and not padding: 

738 raise ValueError('padding must be specified') 

739 

740 evp_cipher_ctx = None 

741 

742 try: 

743 evp_cipher_ctx = libcrypto.EVP_CIPHER_CTX_new() 

744 if is_null(evp_cipher_ctx): 

745 handle_openssl_error(0) 

746 

747 evp_cipher, buffer_size = _setup_evp_encrypt_decrypt(cipher, data) 

748 

749 if iv is None: 

750 iv = null() 

751 

752 if cipher in set(['rc2', 'rc4']): 

753 res = libcrypto.EVP_DecryptInit_ex(evp_cipher_ctx, evp_cipher, null(), null(), null()) 

754 handle_openssl_error(res) 

755 res = libcrypto.EVP_CIPHER_CTX_set_key_length(evp_cipher_ctx, len(key)) 

756 handle_openssl_error(res) 

757 if cipher == 'rc2': 

758 res = libcrypto.EVP_CIPHER_CTX_ctrl( 

759 evp_cipher_ctx, 

760 LibcryptoConst.EVP_CTRL_SET_RC2_KEY_BITS, 

761 len(key) * 8, 

762 null() 

763 ) 

764 handle_openssl_error(res) 

765 evp_cipher = null() 

766 

767 res = libcrypto.EVP_DecryptInit_ex(evp_cipher_ctx, evp_cipher, null(), key, iv) 

768 handle_openssl_error(res) 

769 

770 if padding is not None: 

771 res = libcrypto.EVP_CIPHER_CTX_set_padding(evp_cipher_ctx, int(padding)) 

772 handle_openssl_error(res) 

773 

774 buffer = buffer_from_bytes(buffer_size) 

775 output_length = new(libcrypto, 'int *') 

776 

777 res = libcrypto.EVP_DecryptUpdate(evp_cipher_ctx, buffer, output_length, data, len(data)) 

778 handle_openssl_error(res) 

779 

780 output = bytes_from_buffer(buffer, deref(output_length)) 

781 

782 res = libcrypto.EVP_DecryptFinal_ex(evp_cipher_ctx, buffer, output_length) 

783 handle_openssl_error(res) 

784 

785 output += bytes_from_buffer(buffer, deref(output_length)) 

786 

787 return output 

788 

789 finally: 

790 if evp_cipher_ctx: 

791 libcrypto.EVP_CIPHER_CTX_free(evp_cipher_ctx) 

792 

793 

794def _setup_evp_encrypt_decrypt(cipher, data): 

795 """ 

796 Creates an EVP_CIPHER pointer object and determines the buffer size 

797 necessary for the parameter specified. 

798 

799 :param evp_cipher_ctx: 

800 An EVP_CIPHER_CTX pointer 

801 

802 :param cipher: 

803 A unicode string of "aes128", "aes192", "aes256", "des", 

804 "tripledes_2key", "tripledes_3key", "rc2", "rc4" 

805 

806 :param key: 

807 The key byte string 

808 

809 :param data: 

810 The plaintext or ciphertext as a byte string 

811 

812 :param padding: 

813 If padding is to be used 

814 

815 :return: 

816 A 2-element tuple with the first element being an EVP_CIPHER pointer 

817 and the second being an integer that is the required buffer size 

818 """ 

819 

820 evp_cipher = { 

821 'aes128': libcrypto.EVP_aes_128_cbc, 

822 'aes192': libcrypto.EVP_aes_192_cbc, 

823 'aes256': libcrypto.EVP_aes_256_cbc, 

824 'rc2': libcrypto.EVP_rc2_cbc, 

825 'rc4': libcrypto.EVP_rc4, 

826 'des': libcrypto.EVP_des_cbc, 

827 'tripledes_2key': libcrypto.EVP_des_ede_cbc, 

828 'tripledes_3key': libcrypto.EVP_des_ede3_cbc, 

829 }[cipher]() 

830 

831 if cipher == 'rc4': 

832 buffer_size = len(data) 

833 else: 

834 block_size = { 

835 'aes128': 16, 

836 'aes192': 16, 

837 'aes256': 16, 

838 'rc2': 8, 

839 'des': 8, 

840 'tripledes_2key': 8, 

841 'tripledes_3key': 8, 

842 }[cipher] 

843 buffer_size = block_size * int(math.ceil(len(data) / block_size)) 

844 

845 return (evp_cipher, buffer_size)