From: Tommi Virtanen Date: Fri, 11 Mar 2011 18:28:58 +0000 (-0800) Subject: auth: Allow using NSS as crypto library. X-Git-Tag: v0.26~175 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=3424e3ac50b3bfbadd77f15c213bb852029997b8;p=ceph.git auth: Allow using NSS as crypto library. Added new configure flag --with-nss that enables this. NSS is also automatically used if it is available and CryptoPP is not; use --without-nss to explicitly forbid this. No change on rgw crypto yet; rgw won't build without CryptoPP for now. NSS initialization is in a static constructor for now. All it does is set some values on in-memory data structures, so as long as no (other) static constructor tries to use it, everything should just work. While this could be moved to common_init, there are several other context initialization steps with NSS, and a later refactoring to share the results of these can just include NSS init as its first operation, at practically no cost. Signed-off-by: Tommi Virtanen --- diff --git a/configure.ac b/configure.ac index 9206ad60d17ba..b324500d4e14d 100644 --- a/configure.ac +++ b/configure.ac @@ -31,8 +31,56 @@ AC_PROG_LIBTOOL # Checks for libraries. AC_CHECK_LIB([m], [pow], [true], AC_MSG_FAILURE([libm not found])) AC_CHECK_LIB([pthread], [pthread_create], [true], AC_MSG_FAILURE([libpthread not found])) -PKG_CHECK_MODULES([CRYPTOPP], [libcrypto++], [], [ - AC_SEARCH_LIBS([_ZTIN8CryptoPP14CBC_EncryptionE], [crypto++ cryptopp], [true], AC_MSG_FAILURE([libcrypto++ not found]), [-lpthread])]) + +# Find some crypto library for us to use, while letting user to decide which one to use. +AC_ARG_WITH([cryptopp], + [AS_HELP_STRING([--with-cryptopp], [Use cryptographic functions from cryptopp])], + [], + [with_cryptopp=check]) +have_cryptopp=no +# this looks clumsy but it's just if A then { success } else { if B then success } +AS_IF([test "x$with_cryptopp" != "xno"], + [PKG_CHECK_MODULES([CRYPTOPP], + [libcrypto++], + [have_cryptopp=yes], + [AC_SEARCH_LIBS([_ZTIN8CryptoPP14CBC_EncryptionE], [crypto++ cryptopp], + [have_cryptopp=yes], + [true], + [-lpthread])])]) +# bail out if given explicit --with-cryptopp +if test "x$have_cryptopp" = "xno" -a "x$with_cryptopp" != "xcheck" -a "x$with_cryptopp" != "xno"; then + AC_MSG_FAILURE([--with-cryptopp was given, but library was not found]) +fi + +AC_ARG_WITH([nss], + [AS_HELP_STRING([--with-nss], [Use cryptographic functions from nss])], + [], + [with_nss=check]) +have_nss=no +AS_IF([test "x$with_nss" != "xno"], + [PKG_CHECK_MODULES([NSS], [nss], [have_nss=yes], [true])]) +# bail out if given explicit --with-nss +if test "x$have_nss" = "xno" -a "x$with_nss" != "xcheck" -a "x$with_nss" != "xno"; then + AC_MSG_FAILURE([--with-nss was given, but library was not found]) +fi + +# now decide which crypto library to really use +if test "x$have_cryptopp" = "xyes"; then + AC_MSG_NOTICE([using cryptopp for cryptography]) + AC_DEFINE([USE_CRYPTOPP], [1], [Define if using CryptoPP.]) + AC_SUBST([CRYPTO_CFLAGS], [$CRYPTOPP_CFLAGS]) + AC_SUBST([CRYPTO_CXXFLAGS], [$CRYPTOPP_CXXFLAGS]) + AC_SUBST([CRYPTO_LIBS], [$CRYPTOPP_LIBS]) +elif test "x$have_nss" = "xyes"; then + AC_MSG_NOTICE([using nss for cryptography]) + AC_DEFINE([USE_NSS], [1], [Define if using NSS.]) + AC_SUBST([CRYPTO_CFLAGS], [$NSS_CFLAGS]) + # this needs CFLAGS too in practise to get the includes right. ugly. + AC_SUBST([CRYPTO_CXXFLAGS], [$NSS_CFLAGS $NSS_CXXFLAGS]) + AC_SUBST([CRYPTO_LIBS], [$NSS_LIBS]) +else + AC_MSG_FAILURE([no suitable crypto library found]) +fi # profiler? AC_ARG_WITH([profiler], diff --git a/src/Makefile.am b/src/Makefile.am index 2ce1aa123cf65..cbea816b5df3b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,19 +26,19 @@ endif # monitor cmon_SOURCES = cmon.cc msg/SimpleMessenger.cc -cmon_LDADD = libmon.a libcrush.a libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +cmon_LDADD = libmon.a libcrush.a libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += cmon # osd cosd_SOURCES = cosd.cc msg/SimpleMessenger.cc objclass/class_debug.cc \ objclass/class_api.cc -cosd_LDADD = libosd.a libos.a libcrush.a libcommon.a -ldl -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +cosd_LDADD = libosd.a libos.a libcrush.a libcommon.a -ldl -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += cosd cosd_CXXFLAGS = ${AM_CXXFLAGS} # mds cmds_SOURCES = cmds.cc msg/SimpleMessenger.cc -cmds_LDADD = libmds.a libosdc.a libcrush.a libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +cmds_LDADD = libmds.a libosdc.a libcrush.a libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += cmds cmds_CXXFLAGS = ${AM_CXXFLAGS} @@ -47,7 +47,7 @@ ceph_SOURCES = \ msg/SimpleMessenger.cc \ tools/ceph.cc \ tools/common.cc -ceph_LDADD = libcrush.a libcommon.a -ledit -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +ceph_LDADD = libcrush.a libcommon.a -ledit -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) ceph_CXXFLAGS = ${AM_CXXFLAGS} if WITH_GTK2 @@ -75,7 +75,7 @@ gceph_SOURCES = \ tools/common.cc \ tools/gceph.cc \ tools/gui.cc -gceph_LDADD = libcrush.a libcommon.a -ledit -lpthread -lm $(CRYPTOPP_LIBS) \ +gceph_LDADD = libcrush.a libcommon.a -ledit -lpthread -lm $(CRYPTO_LIBS) \ $(GTKMM_LIBS) $(EXTRALIBS) gceph_CXXFLAGS = ${AM_CXXFLAGS} $(GTKMM_CFLAGS) \ -DCEPH_TOOL_GUIDIR="\"${ceph_tool_guidir}\"" @@ -83,17 +83,17 @@ bin_PROGRAMS += gceph endif cconf_SOURCES = cconf.cc -cconf_LDADD = libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +cconf_LDADD = libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) cauthtool_SOURCES = cauthtool.cc -cauthtool_LDADD = libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +cauthtool_LDADD = libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += ceph cconf cauthtool monmaptool_SOURCES = monmaptool.cc -monmaptool_LDADD = libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +monmaptool_LDADD = libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) crushtool_SOURCES = crushtool.cc -crushtool_LDADD = libcrush.a libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +crushtool_LDADD = libcrush.a libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) osdmaptool_SOURCES = osdmaptool.cc -osdmaptool_LDADD = libcrush.a libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +osdmaptool_LDADD = libcrush.a libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += monmaptool crushtool osdmaptool mount_ceph_SOURCES = mount/mount.ceph.c @@ -109,7 +109,7 @@ bin_PROGRAMS += librados-config # synthetic client csyn_SOURCES = csyn.cc msg/SimpleMessenger.cc -csyn_LDADD = libclient.a libosdc.a libcrush.a libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +csyn_LDADD = libclient.a libosdc.a libcrush.a libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += csyn core: cmon cosd cmds ceph cephfs librados-config cconf monmaptool osdmaptool crushtool csyn @@ -118,7 +118,7 @@ core: cmon cosd cmds ceph cephfs librados-config cconf monmaptool osdmaptool cru # fuse targets? if WITH_FUSE cfuse_SOURCES = cfuse.cc msg/SimpleMessenger.cc client/fuse_ll.cc -cfuse_LDADD = -lfuse libclient.a libosdc.a libcrush.a libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +cfuse_LDADD = -lfuse libclient.a libosdc.a libcrush.a libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) cfuse_CXXFLAGS = ${AM_CXXFLAGS} bin_PROGRAMS += cfuse @@ -146,30 +146,30 @@ endif # WITH_TCMALLOC if WITH_DEBUG psim_SOURCES = psim.cc -psim_LDADD = libcrush.a libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +psim_LDADD = libcrush.a libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += psim testmsgr_SOURCES = testmsgr.cc msg/SimpleMessenger.cc -testmsgr_LDADD = libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +testmsgr_LDADD = libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += testmsgr test_ioctls_SOURCES = client/test_ioctls.c bin_PROGRAMS += test_ioctls dumpjournal_SOURCES = dumpjournal.cc msg/SimpleMessenger.cc -dumpjournal_LDADD = libosdc.a libcrush.a libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +dumpjournal_LDADD = libosdc.a libcrush.a libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) dupstore_SOURCES = dupstore.cc -dupstore_LDADD = libos.a libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +dupstore_LDADD = libos.a libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) streamtest_SOURCES = streamtest.cc -streamtest_LDADD = libos.a libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +streamtest_LDADD = libos.a libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += dumpjournal dupstore streamtest test_trans_SOURCES = test_trans.cc -test_trans_LDADD = libos.a libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +test_trans_LDADD = libos.a libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += test_trans testsnaps_SOURCES = test/osd/TestSnaps.cc -testsnaps_LDADD = librados.la -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +testsnaps_LDADD = librados.la -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += testsnaps endif @@ -198,19 +198,19 @@ libceph_la_SOURCES = \ msg/SimpleMessenger.cc \ ${libcommon_a_SOURCES} \ ${libosdc_a_SOURCES} -libceph_la_CFLAGS = ${AM_CFLAGS} -libceph_la_CXXFLAGS= ${AM_CXXFLAGS} -libceph_la_LIBADD = libcrush.la -lpthread $(CRYPTOPP_LIBS) $(EXTRALIBS) +libceph_la_CFLAGS= ${CRYPTO_CFLAGS} ${AM_CFLAGS} +libceph_la_CXXFLAGS= ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS} +libceph_la_LIBADD = libcrush.la -lpthread $(CRYPTO_LIBS) $(EXTRALIBS) libceph_la_LDFLAGS = ${AM_LDFLAGS} -version-info 1:0:0 -export-symbols-regex '^ceph_.*' lib_LTLIBRARIES += libceph.la if WITH_DEBUG testceph_SOURCES = client/testceph.cc -testceph_LDADD = libceph.la libcrush.la -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +testceph_LDADD = libceph.la libcrush.la -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += testceph testtimers_SOURCES = test/TestTimers.cc -testtimers_LDADD = libceph.la libcrush.la -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +testtimers_LDADD = libceph.la libcrush.la -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += testtimers testdout_streambuf_SOURCES = test/TestDoutStreambuf.cc @@ -230,15 +230,15 @@ librados_SOURCES = \ osdc/Objecter.cc \ ${libcommon_a_SOURCES} librados_la_SOURCES = ${librados_SOURCES} -librados_la_CFLAGS = ${AM_CFLAGS} -librados_la_CXXFLAGS = ${AM_CXXFLAGS} -librados_la_LIBADD = libcrush.la -lpthread $(CRYPTOPP_LIBS) $(EXTRALIBS) +librados_la_CFLAGS = ${CRYPTO_CFLAGS} ${AM_CFLAGS} +librados_la_CXXFLAGS = ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS} +librados_la_LIBADD = libcrush.la -lpthread $(CRYPTO_LIBS) $(EXTRALIBS) librados_la_LDFLAGS = ${AM_LDFLAGS} -version-info 2:0:0 -export-symbols-regex '^rados_.*' lib_LTLIBRARIES += librados.la librados_a_SOURCES = ${librados_SOURCES} -librados_a_CFLAGS = ${AM_CFLAGS} -librados_a_CXXFLAGS = ${AM_CXXFLAGS} +librados_a_CFLAGS = ${CRYPTO_CFLAGS} ${AM_CFLAGS} +librados_a_CXXFLAGS = ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS} # librbd librbd_SOURCES = \ @@ -247,7 +247,7 @@ librbd_SOURCES = \ librbd_la_SOURCES = ${librbd_SOURCES} librbd_la_CFLAGS = ${AM_CFLAGS} librbd_la_CXXFLAGS = ${AM_CXXFLAGS} -librbd_la_LIBADD = librados.la libcrush.la -lpthread $(CRYPTOPP_LIBS) $(EXTRALIBS) +librbd_la_LIBADD = librados.la libcrush.la -lpthread $(CRYPTO_LIBS) $(EXTRALIBS) librbd_la_LDFLAGS = ${AM_LDFLAGS} -version-info 1:0:0 -export-symbols-regex '^rbd_.*' lib_LTLIBRARIES += librbd.la @@ -256,31 +256,31 @@ librbd_a_CFLAGS = ${AM_CFLAGS} librbd_a_CXXFLAGS = ${AM_CXXFLAGS} rados_SOURCES = rados.cc -rados_LDADD = librados.la -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +rados_LDADD = librados.la -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += rados if WITH_DEBUG testrados_SOURCES = testrados.c -testrados_LDADD = librados.la -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +testrados_LDADD = librados.la -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) testradospp_SOURCES = testradospp.cc testradospp_LDADD = librados.la -lpthread -lm radosacl_SOURCES = radosacl.cc -radosacl_LDADD = librados.la -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +radosacl_LDADD = librados.la -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += testrados testradospp radosacl endif rbd_SOURCES = rbd.cc common/fiemap.cc rbd_CXXFLAGS = ${AM_CXXFLAGS} -rbd_LDADD = librbd.la librados.la libcrush.la -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +rbd_LDADD = librbd.la librados.la libcrush.la -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += rbd if WITH_DEBUG testlibrbd_SOURCES = testlibrbd.c testlibrbd_LDADD = librbd.la librados.la libcrush.la -lpthread -lm \ - $(CRYPTOPP_LIBS) $(EXTRALIBS) + $(CRYPTO_LIBS) $(EXTRALIBS) testlibrbdpp_SOURCES = testlibrbdpp.cc testlibrbdpp_LDADD = librbd.la librados.la libcrush.la -lpthread -lm \ - $(CRYPTOPP_LIBS) $(EXTRALIBS) + $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += testlibrbd testlibrbdpp endif @@ -299,21 +299,21 @@ libradosgw_a_CXXFLAGS = ${AM_CXXFLAGS} # lib_LTLIBRARIES += libradosgw.a radosgw_SOURCES = rgw/rgw_main.cc -radosgw_LDADD = libradosgw.a librados.a libcrush.a -lfcgi -lexpat -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +radosgw_LDADD = libradosgw.a librados.a libcrush.a -lfcgi -lexpat -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) radosgw_CXXFLAGS = ${AM_CXXFLAGS} radosgw_admin_SOURCES = rgw/rgw_admin.cc -radosgw_admin_LDADD = libradosgw.a librados.a libcrush.a -lfcgi -lexpat -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +radosgw_admin_LDADD = libradosgw.a librados.a libcrush.a -lfcgi -lexpat -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += radosgw radosgw_admin endif if WITH_DEBUG testcrypto_SOURCES = testcrypto.cc -testcrypto_LDADD = libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +testcrypto_LDADD = libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) testcrypto_CXXFLAGS = ${AM_CXXFLAGS} bin_PROGRAMS += testcrypto testkeys_SOURCES = testkeys.cc -testkeys_LDADD = libmon.a libcommon.a -lpthread -lm $(CRYPTOPP_LIBS) $(EXTRALIBS) +testkeys_LDADD = libmon.a libcommon.a -lpthread -lm $(CRYPTO_LIBS) $(EXTRALIBS) testkeys_CXXFLAGS = ${AM_CXXFLAGS} bin_PROGRAMS += testkeys endif @@ -518,6 +518,9 @@ libcommon_a_SOURCES = \ ./ceph_ver.c \ $(libcommon_files) +libcommon_a_CFLAGS= ${CRYPTO_CFLAGS} ${AM_CFLAGS} +libcommon_a_CXXFLAGS= ${CRYPTO_CXXFLAGS} ${AM_CXXFLAGS} + # this list ommits the ceph_ver.c file libcommon_files = \ auth/AuthAuthorizeHandler.cc \ diff --git a/src/auth/Crypto.cc b/src/auth/Crypto.cc index bbce59b3d738e..d9b599d5681cc 100644 --- a/src/auth/Crypto.cc +++ b/src/auth/Crypto.cc @@ -11,10 +11,17 @@ * */ +#include #include "Crypto.h" -#include -#include -#include +#ifdef USE_CRYPTOPP +# include +# include +# include +#elif USE_NSS +# include +# include +# include +#endif #include "include/ceph_fs.h" #include "common/config.h" @@ -82,12 +89,137 @@ int CryptoNone::decrypt(bufferptr& secret, const bufferlist& in, bufferlist& out // --------------------------------------------------- -#define AES_KEY_LEN ((size_t)CryptoPP::AES::DEFAULT_KEYLENGTH) -#define AES_BLOCK_LEN ((size_t)CryptoPP::AES::BLOCKSIZE) +#ifdef USE_CRYPTOPP +# define AES_KEY_LEN ((size_t)CryptoPP::AES::DEFAULT_KEYLENGTH) +# define AES_BLOCK_LEN ((size_t)CryptoPP::AES::BLOCKSIZE) +#elif USE_NSS +// when we say AES, we mean AES-128 +# define AES_KEY_LEN 16 +# define AES_BLOCK_LEN 16 + +static int nss_aes_operation(CK_ATTRIBUTE_TYPE op, bufferptr& secret, const bufferlist& in, bufferlist& out) { + const CK_MECHANISM_TYPE mechanism = CKM_AES_CBC_PAD; + + // sample source said this has to be at least size of input + 8, + // but i see 15 still fail with SEC_ERROR_OUTPUT_LEN + bufferptr out_tmp(in.length()+16); + int err = -EINVAL; + + PK11SlotInfo *slot; + + slot = PK11_GetBestSlot(mechanism, NULL); + if (!slot) { + dout(0) << "cannot find NSS slot to use: " << PR_GetError() << dendl; + goto err; + } + + SECItem keyItem; + + keyItem.type = siBuffer; + keyItem.data = (unsigned char*)secret.c_str(); + keyItem.len = secret.length(); + + PK11SymKey *key; + + key = PK11_ImportSymKey(slot, mechanism, PK11_OriginUnwrap, CKA_ENCRYPT, + &keyItem, NULL); + if (!key) { + dout(0) << "cannot convert AES key for NSS: " << PR_GetError() << dendl; + goto err_slot; + } + + SECItem ivItem; + + ivItem.type = siBuffer; + // losing constness due to SECItem.data; IV should never be + // modified, regardless + ivItem.data = (unsigned char*)CEPH_AES_IV; + ivItem.len = sizeof(CEPH_AES_IV); + + SECItem *param; + + param = PK11_ParamFromIV(mechanism, &ivItem); + if (!param) { + dout(0) << "cannot set NSS IV param: " << PR_GetError() << dendl; + goto err_key; + } + + PK11Context *ctx; + + ctx = PK11_CreateContextBySymKey(mechanism, op, key, param); + if (!ctx) { + dout(0) << "cannot create NSS context: " << PR_GetError() << dendl; + goto err_param; + } + + SECStatus ret; + int written; + // in is const, and PK11_CipherOp is not; C++ makes this hard to cheat, + // so just copy it to a temp buffer, at least for now + unsigned in_len; + unsigned char *in_buf; + in_len = in.length(); + in_buf = (unsigned char*)malloc(in_len); + if (!in_buf) { + dout(0) << "NSS out of memory" << dendl; + err = -ENOMEM; + goto err_ctx; + } + in.copy(0, in_len, (char*)in_buf); + ret = PK11_CipherOp(ctx, (unsigned char*)out_tmp.c_str(), &written, out_tmp.length(), + in_buf, in.length()); + free(in_buf); + if (ret != SECSuccess) { + dout(0) << "NSS AES failed: " << PR_GetError() << dendl; + goto err_op; + } + + unsigned int written2; + ret = PK11_DigestFinal(ctx, (unsigned char*)out_tmp.c_str()+written, &written2, + out_tmp.length()-written); + if (ret != SECSuccess) { + dout(0) << "NSS AES final round failed: " << PR_GetError() << dendl; + goto err_op; + } + + PK11_DestroyContext(ctx, PR_TRUE); + out_tmp.set_length(written + written2); + out.append(out_tmp); + return out_tmp.length(); + + err_op: + err_ctx: + PK11_DestroyContext(ctx, PR_TRUE); + err_param: + SECITEM_FreeItem(param, PR_TRUE); + err_key: + PK11_FreeSymKey(key); + err_slot: + PK11_FreeSlot(slot); + err: + return err; +} + +#else +# error "No supported crypto implementation found." +#endif class CryptoAES : public CryptoHandler { public: - CryptoAES() {} + CryptoAES() { +#ifdef USE_NSS + SECStatus ret; + ret = NSS_NoDB_Init(NULL); + if (ret != SECSuccess) { + dout(0) << "initializing NSS crypto library failed (code " + << PR_GetError() << "), aborting" << dendl; + exit(1); + } + + +#endif + } + ~CryptoAES() {} int create(bufferptr& secret); int validate_secret(bufferptr& secret); @@ -117,40 +249,49 @@ int CryptoAES::validate_secret(bufferptr& secret) int CryptoAES::encrypt(bufferptr& secret, const bufferlist& in, bufferlist& out) { - const unsigned char *key = (const unsigned char *)secret.c_str(); - const unsigned char *in_buf; - if (secret.length() < AES_KEY_LEN) { dout(0) << "key is too short" << dendl; return false; } - string ciphertext; - CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); - CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, (const byte*)CEPH_AES_IV ); - CryptoPP::StringSink *sink = new CryptoPP::StringSink(ciphertext); - if (!sink) - return false; - CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, sink); - - for (std::list::const_iterator it = in.buffers().begin(); - it != in.buffers().end(); it++) { - in_buf = (const unsigned char *)it->c_str(); - - stfEncryptor.Put(in_buf, it->length()); - } - try { - stfEncryptor.MessageEnd(); - } catch (CryptoPP::Exception& e) { - dout(0) << "encryptor.MessageEnd::Exception: " << e.GetWhat() << dendl; - return false; +#ifdef USE_CRYPTOPP + { + const unsigned char *key = (const unsigned char *)secret.c_str(); + const unsigned char *in_buf; + + string ciphertext; + CryptoPP::AES::Encryption aesEncryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); + CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, (const byte*)CEPH_AES_IV ); + CryptoPP::StringSink *sink = new CryptoPP::StringSink(ciphertext); + if (!sink) + return false; + CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, sink); + + for (std::list::const_iterator it = in.buffers().begin(); + it != in.buffers().end(); it++) { + in_buf = (const unsigned char *)it->c_str(); + + stfEncryptor.Put(in_buf, it->length()); + } + try { + stfEncryptor.MessageEnd(); + } catch (CryptoPP::Exception& e) { + dout(0) << "encryptor.MessageEnd::Exception: " << e.GetWhat() << dendl; + return false; + } + out.append((const char *)ciphertext.c_str(), ciphertext.length()); } - out.append((const char *)ciphertext.c_str(), ciphertext.length()); - +#elif USE_NSS + // the return type may be int but this CryptoAES::encrypt returns bools + return (nss_aes_operation(CKA_ENCRYPT, secret, in, out) >= 0); +#else +# error "No supported crypto implementation found." +#endif return true; } int CryptoAES::decrypt(bufferptr& secret, const bufferlist& in, bufferlist& out) { +#ifdef USE_CRYPTOPP const unsigned char *key = (const unsigned char *)secret.c_str(); CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); @@ -176,6 +317,11 @@ int CryptoAES::decrypt(bufferptr& secret, const bufferlist& in, bufferlist& out) out.append((const char *)decryptedtext.c_str(), decryptedtext.length()); return decryptedtext.length(); +#elif USE_NSS + return nss_aes_operation(CKA_DECRYPT, secret, in, out); +#else +# error "No supported crypto implementation found." +#endif }