PostgreSQL Source Code: contrib/pgcrypto/openssl.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

33

34#include <openssl/crypto.h>

35#include <openssl/evp.h>

36#include <openssl/err.h>

37#include <openssl/rand.h>

38

39#include "px.h"

42

43

44

45

46#define MAX_KEY (512/8)

47#define MAX_IV (128/8)

48

49

50

51

52

53

54

55

56

58{

61

64

65

67

69{

70 .name = "pgcrypto OpenSSL digest handle",

74 .DebugPrint = NULL,

75};

76

77

78static inline void

80{

82}

83static inline void

85{

87}

88

89static void

91{

92 EVP_MD_CTX_destroy(digest->ctx);

93 if (digest->owner != NULL)

96}

97

98static unsigned

100{

102 int result = EVP_MD_CTX_size(digest->ctx);

103

104 if (result < 0)

105 elog(ERROR, "EVP_MD_CTX_size() failed");

106

107 return result;

108}

109

110static unsigned

112{

114 int result = EVP_MD_CTX_block_size(digest->ctx);

115

116 if (result < 0)

117 elog(ERROR, "EVP_MD_CTX_block_size() failed");

118

119 return result;

120}

121

122static void

124{

126

127 if (!EVP_DigestInit_ex(digest->ctx, digest->algo, NULL))

128 elog(ERROR, "EVP_DigestInit_ex() failed");

129}

130

131static void

133{

135

136 if (!EVP_DigestUpdate(digest->ctx, data, dlen))

137 elog(ERROR, "EVP_DigestUpdate() failed");

138}

139

140static void

142{

144

145 if (!EVP_DigestFinal_ex(digest->ctx, dst, NULL))

146 elog(ERROR, "EVP_DigestFinal_ex() failed");

147}

148

149static void

151{

153

156}

157

158

159

160int

162{

163 const EVP_MD *md;

164 EVP_MD_CTX *ctx;

167

168 md = EVP_get_digestbyname(name);

169 if (md == NULL)

171

173

174

175

176

177

178

180

181 ctx = EVP_MD_CTX_create();

182 if (!ctx)

183 {

186 }

187 if (EVP_DigestInit_ex(ctx, md, NULL) == 0)

188 {

189 EVP_MD_CTX_destroy(ctx);

192 }

193

194 digest->algo = md;

195 digest->ctx = ctx;

198

199

200 h = palloc(sizeof(*h));

207 h->p.ptr = digest;

208

209 *res = h;

210 return 0;

211}

212

213

214

215static void

217{

219

220 digest->owner = NULL;

222}

223

224

225

226

227

228

229

230

231

232

233

234typedef const EVP_CIPHER *(*ossl_EVP_cipher_func) (void);

235

236

237

238

240{

245};

246

247

248

249

250

251

252

253

255{

263

266

267

269

271{

272 .name = "pgcrypto OpenSSL cipher handle",

276 .DebugPrint = NULL,

277};

278

279

280static inline void

282{

284}

285static inline void

287{

289}

290

291static void

293{

294 EVP_CIPHER_CTX_free(od->evp_ctx);

295 if (od->owner != NULL)

298}

299

300

301

302static unsigned

304{

306

308}

309

310static unsigned

312{

314

316}

317

318static unsigned

320{

321 unsigned ivlen;

323

325 return ivlen;

326}

327

328static void

330{

332

335}

336

337static int

339 uint8 *res, unsigned *rlen)

340{

342 int outlen,

343 outlen2;

344

345 if (!od->init)

346 {

347 if (!EVP_DecryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))

349 if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, padding))

351 if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))

353 if (!EVP_DecryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))

355 od->init = true;

356 }

357

358 if (!EVP_DecryptUpdate(od->evp_ctx, res, &outlen, data, dlen))

360 if (!EVP_DecryptFinal_ex(od->evp_ctx, res + outlen, &outlen2))

362 *rlen = outlen + outlen2;

363

364 return 0;

365}

366

367static int

369 uint8 *res, unsigned *rlen)

370{

372 int outlen,

373 outlen2;

374

375 if (!od->init)

376 {

377 if (!EVP_EncryptInit_ex(od->evp_ctx, od->evp_ciph, NULL, NULL, NULL))

379 if (!EVP_CIPHER_CTX_set_padding(od->evp_ctx, padding))

381 if (!EVP_CIPHER_CTX_set_key_length(od->evp_ctx, od->klen))

383 if (!EVP_EncryptInit_ex(od->evp_ctx, NULL, NULL, od->key, od->iv))

385 od->init = true;

386 }

387

388 if (!EVP_EncryptUpdate(od->evp_ctx, res, &outlen, data, dlen))

390 if (!EVP_EncryptFinal_ex(od->evp_ctx, res + outlen, &outlen2))

392 *rlen = outlen + outlen2;

393

394 return 0;

395}

396

397

398

399

400

401

402

403

404static int

406{

407 static const uint8 key[56] = {

408 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0x78, 0x69,

409 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, 0x00, 0x11, 0x22, 0x33,

410 0x44, 0x55, 0x66, 0x77, 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd,

411 0x3b, 0x2f, 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,

412 0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e, 0xff, 0xff,

413 0xff, 0xff, 0xff, 0xff, 0xff, 0xff

414 };

415

416 static const uint8 data[8] = {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};

417 static const uint8 res[8] = {0xc0, 0x45, 0x04, 0x01, 0x2e, 0x4e, 0x1f, 0x53};

419 EVP_CIPHER_CTX *evp_ctx;

420 int outlen;

421 int status = 0;

422

423

424 evp_ctx = EVP_CIPHER_CTX_new();

425 if (!evp_ctx)

426 return 0;

427 if (!EVP_EncryptInit_ex(evp_ctx, EVP_bf_ecb(), NULL, NULL, NULL))

428 goto leave;

429 if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, 56))

430 goto leave;

431 if (!EVP_EncryptInit_ex(evp_ctx, NULL, NULL, key, NULL))

432 goto leave;

433

434 if (!EVP_EncryptUpdate(evp_ctx, out, &outlen, data, 8))

435 goto leave;

436

437 if (memcmp(out, res, 8) != 0)

438 goto leave;

439

440 status = 1;

441

442leave:

443 EVP_CIPHER_CTX_free(evp_ctx);

444 return status;

445}

446

447static int

449{

452 static int bf_is_strong = -1;

453

454

455

456

457

458

459

460 if (bf_is_strong == -1)

462

463 if (!bf_is_strong && klen > 16)

465

466

467 od->klen = klen;

468 memcpy(od->key, key, klen);

469

470 if (iv)

471 memcpy(od->iv, iv, bs);

472 else

473 memset(od->iv, 0, bs);

474 return 0;

475}

476

477

478

479static int

481{

484

485 od->klen = 8;

486 memset(od->key, 0, 8);

487 memcpy(od->key, key, klen > 8 ? 8 : klen);

488

489 if (iv)

490 memcpy(od->iv, iv, bs);

491 else

492 memset(od->iv, 0, bs);

493 return 0;

494}

495

496

497

498static int

500{

503

504 od->klen = 24;

505 memset(od->key, 0, 24);

506 memcpy(od->key, key, klen > 24 ? 24 : klen);

507

508 if (iv)

509 memcpy(od->iv, iv, bs);

510 else

511 memset(od->iv, 0, bs);

512 return 0;

513}

514

515

516

517static int

519{

522

523 od->klen = klen;

524 memcpy(od->key, key, klen);

525

526 if (iv)

527 memcpy(od->iv, iv, bs);

528 else

529 memset(od->iv, 0, bs);

530 return 0;

531}

532

533

534

535static int

537{

540

541 if (klen <= 128 / 8)

542 od->klen = 128 / 8;

543 else if (klen <= 192 / 8)

544 od->klen = 192 / 8;

545 else if (klen <= 256 / 8)

546 od->klen = 256 / 8;

547 else

549

550 memcpy(od->key, key, klen);

551

552 if (iv)

553 memcpy(od->iv, iv, bs);

554 else

555 memset(od->iv, 0, bs);

556

557 return 0;

558}

559

560static int

562{

565

568 return err;

569

570 switch (od->klen)

571 {

572 case 128 / 8:

573 od->evp_ciph = EVP_aes_128_ecb();

574 break;

575 case 192 / 8:

576 od->evp_ciph = EVP_aes_192_ecb();

577 break;

578 case 256 / 8:

579 od->evp_ciph = EVP_aes_256_ecb();

580 break;

581 default:

582

584 break;

585 }

586

587 return err;

588}

589

590static int

592{

595

598 return err;

599

600 switch (od->klen)

601 {

602 case 128 / 8:

603 od->evp_ciph = EVP_aes_128_cbc();

604 break;

605 case 192 / 8:

606 od->evp_ciph = EVP_aes_192_cbc();

607 break;

608 case 256 / 8:

609 od->evp_ciph = EVP_aes_256_cbc();

610 break;

611 default:

612

614 break;

615 }

616

617 return err;

618}

619

620static int

622{

625

628 return err;

629

630 switch (od->klen)

631 {

632 case 128 / 8:

633 od->evp_ciph = EVP_aes_128_cfb();

634 break;

635 case 192 / 8:

636 od->evp_ciph = EVP_aes_192_cfb();

637 break;

638 case 256 / 8:

639 od->evp_ciph = EVP_aes_256_cfb();

640 break;

641 default:

642

644 break;

645 }

646

647 return err;

648}

649

650

651

652

653

655 {"bf", "bf-cbc"},

656 {"blowfish", "bf-cbc"},

657 {"blowfish-cbc", "bf-cbc"},

658 {"blowfish-ecb", "bf-ecb"},

659 {"blowfish-cfb", "bf-cfb"},

660 {"des", "des-cbc"},

661 {"3des", "des3-cbc"},

662 {"3des-ecb", "des3-ecb"},

663 {"3des-cbc", "des3-cbc"},

664 {"cast5", "cast5-cbc"},

665 {"aes", "aes-cbc"},

666 {"rijndael", "aes-cbc"},

667 {"rijndael-cbc", "aes-cbc"},

668 {"rijndael-ecb", "aes-ecb"},

669 {"rijndael-cfb", "aes-cfb"},

670 {NULL}

671};

672

675 EVP_bf_cbc,

676 64 / 8, 448 / 8

677};

678

681 EVP_bf_ecb,

682 64 / 8, 448 / 8

683};

684

687 EVP_bf_cfb,

688 64 / 8, 448 / 8

689};

690

693 EVP_des_ecb,

694 64 / 8, 64 / 8

695};

696

699 EVP_des_cbc,

700 64 / 8, 64 / 8

701};

702

705 EVP_des_ede3_ecb,

706 64 / 8, 192 / 8

707};

708

711 EVP_des_ede3_cbc,

712 64 / 8, 192 / 8

713};

714

717 EVP_cast5_ecb,

718 64 / 8, 128 / 8

719};

720

723 EVP_cast5_cbc,

724 64 / 8, 128 / 8

725};

726

729 NULL,

730

731 128 / 8, 256 / 8

732};

733

736 NULL,

737

738 128 / 8, 256 / 8

739};

740

743 NULL,

744

745 128 / 8, 256 / 8

746};

747

748

749

750

752{

755};

756

770 {NULL}

771};

772

773

774

775int

777{

780 EVP_CIPHER_CTX *ctx;

782

785 if (strcmp(i->name, name) == 0)

786 break;

787 if (i->name == NULL)

789

791

792

793

794

795

796

798 od->ciph = i->ciph;

799

800

801 ctx = EVP_CIPHER_CTX_new();

802 if (!ctx)

803 {

806 }

807

811

812 if (i->ciph->cipher_func)

813 od->evp_ciph = i->ciph->cipher_func();

814

815

824 c->ptr = od;

825

826 *res = c;

827 return 0;

828}

829

830

831

832static void

834{

836}

837

838

839

840

841

842

843bool

845{

846 int fips_enabled = 0;

847

848

849

850

851

852

853

854

855 fips_enabled =

856#if OPENSSL_VERSION_NUMBER >= 0x30000000L

857 EVP_default_properties_is_fips_enabled(NULL);

858#else

859 FIPS_mode();

860#endif

861

862 return (fips_enabled == 1);

863}

864

865

866

867

868

869

870

871

872

873void

875{

877 return;

878

881 errmsg("use of built-in crypto functions is disabled"));

882

884

887 errmsg("use of non-FIPS validated crypto not allowed when OpenSSL is in FIPS mode"));

888}

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

void err(int eval, const char *fmt,...)

Assert(PointerIsAligned(start, uint64))

if(TABLE==NULL||TABLE_index==NULL)

void * MemoryContextAlloc(MemoryContext context, Size size)

void * MemoryContextAllocZero(MemoryContext context, Size size)

void pfree(void *pointer)

MemoryContext TopMemoryContext

static unsigned gen_ossl_block_size(PX_Cipher *c)

int px_find_digest(const char *name, PX_MD **res)

void CheckBuiltinCryptoMode(void)

static const struct ossl_cipher ossl_des_ecb

static const struct ossl_cipher ossl_des3_cbc

static void digest_update(PX_MD *h, const uint8 *data, unsigned dlen)

static int bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)

static int bf_check_supported_key_len(void)

static void ResourceOwnerForgetOSSLDigest(ResourceOwner owner, OSSLDigest *digest)

static unsigned digest_result_size(PX_MD *h)

static const struct ossl_cipher ossl_aes_ecb

static void ResourceOwnerRememberOSSLDigest(ResourceOwner owner, OSSLDigest *digest)

static void digest_finish(PX_MD *h, uint8 *dst)

struct OSSLCipher OSSLCipher

static const struct ossl_cipher ossl_aes_cfb

static const ResourceOwnerDesc ossldigest_resowner_desc

static void free_openssl_cipher(OSSLCipher *od)

const EVP_CIPHER *(* ossl_EVP_cipher_func)(void)

static void ResourceOwnerForgetOSSLCipher(ResourceOwner owner, OSSLCipher *od)

static unsigned gen_ossl_key_size(PX_Cipher *c)

static int ossl_aes_ecb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)

static const struct ossl_cipher ossl_des3_ecb

static void ResOwnerReleaseOSSLCipher(Datum res)

static const struct ossl_cipher ossl_bf_cfb

struct OSSLDigest OSSLDigest

static int gen_ossl_encrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)

static const struct ossl_cipher ossl_cast_cbc

static const ResourceOwnerDesc osslcipher_resowner_desc

static int gen_ossl_decrypt(PX_Cipher *c, int padding, const uint8 *data, unsigned dlen, uint8 *res, unsigned *rlen)

static void gen_ossl_free(PX_Cipher *c)

static const struct ossl_cipher ossl_des_cbc

static void digest_reset(PX_MD *h)

static void ResOwnerReleaseOSSLDigest(Datum res)

static int ossl_cast_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)

static unsigned gen_ossl_iv_size(PX_Cipher *c)

int px_find_cipher(const char *name, PX_Cipher **res)

static const struct ossl_cipher ossl_bf_ecb

static PX_Alias ossl_aliases[]

static const struct ossl_cipher ossl_bf_cbc

static const struct ossl_cipher_lookup ossl_cipher_types[]

static void free_openssl_digest(OSSLDigest *digest)

static const struct ossl_cipher ossl_cast_ecb

static int ossl_aes_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)

static int ossl_aes_cfb_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)

static unsigned digest_block_size(PX_MD *h)

static const struct ossl_cipher ossl_aes_cbc

static int ossl_aes_cbc_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)

static void digest_free(PX_MD *h)

static int ossl_des3_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)

static void ResourceOwnerRememberOSSLCipher(ResourceOwner owner, OSSLCipher *od)

static int ossl_des_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)

int builtin_crypto_enabled

static Datum PointerGetDatum(const void *X)

static Pointer DatumGetPointer(Datum X)

const char * px_resolve_alias(const PX_Alias *list, const char *name)

#define PXE_DECRYPT_FAILED

#define PXE_ENCRYPT_FAILED

ResourceOwner CurrentResourceOwner

void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)

void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)

void ResourceOwnerEnlarge(ResourceOwner owner)

@ RESOURCE_RELEASE_BEFORE_LOCKS

#define RELEASE_PRIO_FIRST

const struct ossl_cipher * ciph

const EVP_CIPHER * evp_ciph

const struct ossl_cipher * ciph

int(* init)(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)

ossl_EVP_cipher_func cipher_func

void(* update)(PX_MD *h, const uint8 *data, unsigned dlen)

unsigned(* result_size)(PX_MD *h)

unsigned(* block_size)(PX_MD *h)

void(* finish)(PX_MD *h, uint8 *dst)