]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Move epoch and cid generation into the rx core
authorBen Kaduk <kaduk@mit.edu>
Tue, 26 Mar 2013 17:41:40 +0000 (13:41 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Wed, 10 Sep 2014 19:05:32 +0000 (15:05 -0400)
Now that we have hcrypto available everywhere, we can get real randomness
in the rx core (both uerspace and kernel), and thus can initialize the
RX epoch to a real random value when first initializing a host; there is
no need to rely on rxkad to produce randomness for this purpose.
Initialize a connection ID counter at the same time, and use that in
rx_NewConnection, also supplanting rxkad-specific logic.

The rxkad-specific logic is removed, and in particular there is no longer
a need to export rxkad_EpochWasSet to the rest of the world.
The code in afs_Daemon() to check whether the rxepoch was set can be
removed, as if the epoch is not set, rx initialization fails.

Add libafshcrypto to LIBS in the handful of places it hadn't crept already,
and likewise afshcrypto.lib in the NTMakefiles.

Change-Id: I1dd1015b29a600aaf72b6b4b36f8a17032453c97
Reviewed-on: http://gerrit.openafs.org/10841
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
21 files changed:
src/afs/afs_daemons.c
src/afsmonitor/Makefile.in
src/auth/test/NTMakefile
src/kauth/test/NTMakefile
src/rx/rx.c
src/rx/test/generator.c
src/rxdebug/Makefile.in
src/rxdebug/NTMakefile
src/rxkad/private_data.h
src/rxkad/rxkad.p.h
src/rxkad/rxkad_client.c
src/rxkad/rxkad_common.c
src/rxkad/test/NTMakefile
src/tools/dumpscan/Makefile.in
src/ubik/Makefile.in
src/ubik/NTMakefile
src/venus/Makefile.in
src/vol/Makefile.in
src/volser/Makefile.in
src/xstat/Makefile.in
src/xstat/NTMakefile

index 4f51b508bf48bc226a778b1e0cf9c134e0ade633..fb79170284e94a4712808c01bfec6cd5d66c3c17 100644 (file)
@@ -36,10 +36,6 @@ struct brequest afs_brs[NBRS];       /* request structures */
 struct afs_osi_WaitHandle AFS_WaitHandler, AFS_CSWaitHandler;
 static int afs_brs_count = 0;  /* request counter, to service reqs in order */
 
-static int rxepoch_checked = 0;
-#define afs_CheckRXEpoch() {if (rxepoch_checked == 0 && rxkad_EpochWasSet) { \
-       rxepoch_checked = 1; afs_GCUserData(/* force flag */ 1);  } }
-
 /* PAG garbage collection */
 /* We induce a compile error if param.h does not define AFS_GCPAGS */
 afs_int32 afs_gcpags = AFS_GCPAGS;
@@ -202,7 +198,6 @@ afs_Daemon(void)
 #if 0
            afs_StoreDirtyVcaches();
 #endif
-           afs_CheckRXEpoch();
            last1MinCheck = now;
        }
 
@@ -1189,7 +1184,7 @@ shutdown_daemons(void)
     AFS_STATCNT(shutdown_daemons);
     if (afs_cold_shutdown) {
        afs_brsDaemons = brsInit = 0;
-       rxepoch_checked = afs_nbrs = 0;
+       afs_nbrs = 0;
        memset(afs_brs, 0, sizeof(afs_brs));
        memset(&afs_xbrs, 0, sizeof(afs_lock_t));
        afs_brsWaiters = 0;
index b8cd1178844c67122c5f60d87e599e581b2d8a12..73ef4d22637ccbe1368fa88fdef14c06f68179c7 100644 (file)
@@ -32,6 +32,7 @@ LIBS=${TOP_LIBDIR}/libxstat_fs.a \
        ${TOP_LIBDIR}/libafsint.a \
        ${TOP_LIBDIR}/libcmd.a \
        ${TOP_LIBDIR}/librx.a \
+       ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${TOP_LIBDIR}/liblwp.a \
        ${TOP_LIBDIR}/libsys.a \
        $(TOP_LIBDIR)/libopr.a \
index b1fa46ca01ca78c038b43a6cfbc8d39d469ae80b..8891d61de79c331e6ded1a82b67c1e5fe372bbd6 100644 (file)
@@ -42,6 +42,7 @@ KTC_EXELIBS =\
        $(DESTDIR)\lib\afs\afsutil.lib \
        $(DESTDIR)\lib\afs\afsauth.lib \
        $(DESTDIR)\lib\afsrx.lib \
+       $(DESTDIR)\lib\afshcrypto.lib \
        $(DESTDIR)\lib\afslwp.lib \
        $(DESTDIR)\lib\afs\afsreg.lib \
        $(DESTDIR)\lib\afs\afspioctl.lib \
index 8a836c7dfff7c560eaa3bff30d3c1828f1b6ed54..a5eebca9394473f2676d22c8444cfdeac093705a 100644 (file)
@@ -17,6 +17,7 @@ EXELIBS = \
        $(DESTDIR)\afsubik.lib \
        $(DESTDIR)\afs\afsprot.lib \
        $(DESTDIR)\afsrx.lib \
+       $(DESTDIR)\lib\afshcrypto.lib \
        $(DESTDIR)\afs\afscom_err.lib \
        $(DESTDIR)\afs\afskauth.lib \
        $(DESTDIR)\lib\afsrfc3961.lib
index 68b7b02ca1d49b6afde051ebfdb2865a8f886c71..07c6d7320f828720866064117610bd64ddee6b64 100644 (file)
@@ -73,6 +73,7 @@ extern afs_int32 afs_termState;
 #endif /* KERNEL */
 
 #include <opr/queue.h>
+#include <hcrypto/rand.h>
 
 #include "rx.h"
 #include "rx_clock.h"
@@ -157,6 +158,7 @@ static void rxi_AckAllInTransmitQueue(struct rx_call *call);
 static void rxi_CancelKeepAliveEvent(struct rx_call *call);
 static void rxi_CancelDelayedAbortEvent(struct rx_call *call);
 static void rxi_CancelGrowMTUEvent(struct rx_call *call);
+static void update_nextCid(void);
 
 #ifdef RX_ENABLE_LOCKS
 struct rx_tq_debug {
@@ -394,6 +396,7 @@ struct rx_connection *rxLastConn = 0;
  * tiers:
  *
  * rx_connHashTable_lock - synchronizes conn creation, rx_connHashTable access
+ *                         also protects updates to rx_nextCid
  * conn_call_lock - used to synchonize rx_EndCall and rx_NewCall
  * call->lock - locks call data fields.
  * These are independent of each other:
@@ -440,13 +443,6 @@ struct rx_serverQueueEntry *rx_waitForPacket = 0;
 
 /* ------------Exported Interfaces------------- */
 
-/* This function allows rxkad to set the epoch to a suitably random number
- * which rx_NewConnection will use in the future.  The principle purpose is to
- * get rxnull connections to use the same epoch as the rxkad connections do, at
- * least once the first rxkad connection is established.  This is important now
- * that the host/port addresses aren't used in FindConnection: the uniqueness
- * of epoch/cid matters and the start time won't do. */
-
 #ifdef AFS_PTHREAD_ENV
 /*
  * This mutex protects the following global variables:
@@ -608,12 +604,12 @@ rx_InitHost(u_int host, u_int port)
 #endif
     }
     rx_stats.minRtt.sec = 9999999;
-#ifdef KERNEL
-    rx_SetEpoch(tv.tv_sec | 0x80000000);
-#else
-    rx_SetEpoch(tv.tv_sec);    /* Start time of this package, rxkad
-                                * will provide a randomer value. */
-#endif
+    if (RAND_bytes(&rx_epoch, sizeof(rx_epoch)) != 1)
+       return -1;
+    rx_epoch  = (rx_epoch & ~0x40000000) | 0x80000000;
+    if (RAND_bytes(&rx_nextCid, sizeof(rx_nextCid)) != 1)
+       return -1;
+    rx_nextCid &= RX_CIDMASK;
     MUTEX_ENTER(&rx_quota_mutex);
     rxi_dataQuota += rx_extraQuota; /* + extra pkts caller asked to rsrv */
     MUTEX_EXIT(&rx_quota_mutex);
@@ -1042,7 +1038,6 @@ rx_NewConnection(afs_uint32 shost, u_short sport, u_short sservice,
                 int serviceSecurityIndex)
 {
     int hashindex, i;
-    afs_int32 cid;
     struct rx_connection *conn;
 
     SPLVAR;
@@ -1063,10 +1058,10 @@ rx_NewConnection(afs_uint32 shost, u_short sport, u_short sservice,
 #endif
     NETPRI;
     MUTEX_ENTER(&rx_connHashTable_lock);
-    cid = (rx_nextCid += RX_MAXCALLS);
     conn->type = RX_CLIENT_CONNECTION;
-    conn->cid = cid;
     conn->epoch = rx_epoch;
+    conn->cid = rx_nextCid;
+    update_nextCid();
     conn->peer = rxi_FindPeer(shost, sport, 1);
     conn->serviceId = sservice;
     conn->securityObject = securityObject;
@@ -6726,6 +6721,19 @@ rxi_CancelGrowMTUEvent(struct rx_call *call)
     }
 }
 
+/*
+ * Increment the counter for the next connection ID, handling overflow.
+ */
+static void
+update_nextCid(void)
+{
+    /* Overflow is technically undefined behavior; avoid it. */
+    if (rx_nextCid > MAX_AFS_INT32 - (1 << RX_CIDSHIFT))
+       rx_nextCid = -1 * ((MAX_AFS_INT32 / RX_CIDSHIFT) * RX_CIDSHIFT);
+    else
+       rx_nextCid += 1 << RX_CIDSHIFT;
+}
+
 static void
 rxi_KeepAliveOn(struct rx_call *call)
 {
index 8f3d929f1175b1d73f377275d9162843e0e9771e..d2cb3e9850a69e1b53bc58b30256a3b5b9090ca1 100644 (file)
@@ -107,6 +107,7 @@ static char *nt_symbols[] = {
 /* all one string */
     "LIBS = $(DESTDIR)/lib/afsrxkad.lib \\\n"
        "\t$(DESTDIR)/lib/afsdes.lib \\\n" "\t$(DESTDIR)/lib/afsrx.lib \\\n"
+       "\t$(DESTDIR)/lib/afshcrypto.lib \\\n"
        "\t$(DESTDIR)/lib/afslwp.lib \\\n"
        "\t$(DESTDIR)/lib/afs/afscmd.lib \\\n"
        "\t$(DESTDIR)/lib/afs/afsafs_com_err.lib \\\n"
index df83359ff7a500d554b2143eeeaa4fe6ffa04938..18dfc331d053eff1a9fbb906353fe49c7727ebc4 100644 (file)
@@ -11,6 +11,7 @@ include @TOP_OBJDIR@/src/config/Makefile.lwp
 
 
 LIBS=${TOP_LIBDIR}/librx.a \
+     ${TOP_LIBDIR}/libafshcrypto_lwp.a \
      ${TOP_LIBDIR}/liblwp.a \
      ${TOP_LIBDIR}/libcmd.a \
      ${TOP_LIBDIR}/libsys.a \
index 21c44163d7b35cbb6218ff9e85f5894b0de83e7d..17bc0e408a28a8309c028d676db60bb1d36b32fc 100644 (file)
@@ -22,6 +22,7 @@ RXDOBJS = $(OUT)\rxdebug.obj \
 LIBDIR  = $(DESTDIR)\lib
 RXDLIBS = $(LIBDIR)\afs\afscmd.lib \
          $(LIBDIR)\afsrx.lib \
+         $(LIBDIR)\afshcrypto.lib \
          $(LIBDIR)\afslwp.lib \
          $(LIBDIR)\afs\afsutil.lib \
           $(LIBDIR)\afs\afsreg.lib \
index fc4ccf6857f3f030211aca8e12180c31e4c70700..b0caeb96cd17453883f53b98bc46e2e09eedb98b 100644 (file)
@@ -36,18 +36,6 @@ struct rxkad_endpoint {
     afs_int32 securityIndex;   /* security index */
 };
 
-/* structure used for generating connection IDs; must be encrypted in network
- * byte order.  Also must be a multiple of 8 bytes for encryption to work
- * properly.
- */
-struct rxkad_cidgen {
-    struct clock time;         /* time now */
-    afs_int32 random1;         /* some implementation-specific random info */
-    afs_int32 random2;         /* more random info */
-    afs_int32 counter;         /* a counter */
-    afs_int32 ipAddr;          /* or an approximation to it */
-};
-
 #define PDATA_SIZE(l) (sizeof(struct rxkad_cprivate) - MAXKTCTICKETLEN + (l))
 
 /* private data in client-side security object */
index 141f534d8046ff92c08c8ff988f74f44fd4309b9..160644d2be59cafac2a2ff689bfed5f03591eff2 100644 (file)
@@ -90,7 +90,6 @@ typedef signed char rxkad_level;
     ((((type) == 1) || ((type) == 2)) ? ((type)-1) : 0)
 
 
-extern int rxkad_EpochWasSet;  /* TRUE => we called rx_SetEpoch */
 /* Get key by enctype.  Takes a rock (path to conf dir), kvno and enctype as
  * input and returns the key and key length.  On input, the keylength parameter
  * must be set to the length of storage allocated by the caller. */
index 71866b71e9a86c28a43a69945c7f80fb57440162..2f894253f96bdaa57b9c6c62bbb90242068cbcbb 100644 (file)
@@ -68,82 +68,6 @@ static struct rx_securityOps rxkad_client_ops = {
     0,
 };
 
-/* To minimize changes to epoch, we set this Cuid once, and everyone (including
- * rxnull) uses it after that.  This means that the Ksession of the first
- * authencticated connection should be a good one. */
-
-#ifdef AFS_PTHREAD_ENV
-/*
- * This mutex protects the following global variables:
- * Cuid
- * counter
- * rxkad_EpochWasSet
- */
-pthread_mutex_t rxkad_client_uid_mutex;
-#define LOCK_CUID osi_Assert(pthread_mutex_lock(&rxkad_client_uid_mutex)==0)
-#define UNLOCK_CUID osi_Assert(pthread_mutex_unlock(&rxkad_client_uid_mutex)==0)
-#else
-#define LOCK_CUID
-#define UNLOCK_CUID
-#endif /* AFS_PTHREAD_ENV */
-
-static afs_int32 Cuid[2];      /* set once and shared by all */
-int rxkad_EpochWasSet = 0;     /* TRUE => we called rx_SetEpoch */
-
-/* allocate a new connetion ID in place */
-int
-rxkad_AllocCID(struct rx_securityClass *aobj, struct rx_connection *aconn)
-{
-    struct rxkad_cprivate *tcp;
-    struct rxkad_cidgen tgen;
-    static afs_int32 counter = 0;      /* not used anymore */
-
-    LOCK_CUID;
-    if (Cuid[0] == 0) {
-       afs_uint32 xor[2];
-       tgen.ipAddr = rxi_getaddr();    /* comes back in net order */
-       clock_GetTime(&tgen.time);      /* changes time1 and time2 */
-       tgen.time.sec = htonl(tgen.time.sec);
-       tgen.time.usec = htonl(tgen.time.usec);
-       tgen.counter = htonl(counter);
-       counter++;
-#ifdef KERNEL
-       tgen.random1 = afs_random() & 0x7fffffff;       /* was "80000" */
-       tgen.random2 = afs_random() & 0x7fffffff;       /* was "htonl(100)" */
-#else
-       tgen.random1 = htonl(getpid());
-       tgen.random2 = htonl(100);
-#endif
-       if (aobj) {
-           /* block is ready for encryption with session key, let's go for it. */
-           tcp = (struct rxkad_cprivate *)aobj->privateData;
-           memcpy((void *)xor, (void *)tcp->ivec, 2 * sizeof(afs_int32));
-           fc_cbc_encrypt((char *)&tgen, (char *)&tgen, sizeof(tgen),
-                          tcp->keysched, xor, ENCRYPT);
-       } else {
-           /* Create a session key so that we can encrypt it */
-
-       }
-       memcpy((void *)Cuid,
-              ((char *)&tgen) + sizeof(tgen) - ENCRYPTIONBLOCKSIZE,
-              ENCRYPTIONBLOCKSIZE);
-       Cuid[0] = (Cuid[0] & ~0x40000000) | 0x80000000;
-       Cuid[1] &= RX_CIDMASK;
-       rx_SetEpoch(Cuid[0]);   /* for future rxnull connections */
-       rxkad_EpochWasSet++;
-    }
-
-    if (!aconn) {
-       UNLOCK_CUID;
-       return 0;
-    }
-    rx_SetConnectionEpoch(aconn, Cuid[0]);
-    rx_SetConnectionId(aconn, Cuid[1]);
-    Cuid[1] += 1 << RX_CIDSHIFT;
-    UNLOCK_CUID;
-    return 0;
-}
-
 /* Allocate a new client security object.  Called with the encryption level,
  * the session key and the ticket for the other side obtained from the
  * AuthServer.  Refers to export control to determine level. */
@@ -287,12 +211,3 @@ rxkad_GetResponse(struct rx_securityClass *aobj, struct rx_connection *aconn,
     rx_SetDataSize(apacket, responseSize + tcp->ticketLen);
     return 0;
 }
-
-void
-rxkad_ResetState(void)
-{
-    LOCK_CUID;
-    Cuid[0] = 0;
-    rxkad_EpochWasSet = 0;
-    UNLOCK_CUID;
-}
index 0f14e4b145f9c011653d9600bc46ea1f07d42a4d..463573c117518dcf72d38efd59b06897bf25f2a0 100644 (file)
@@ -70,7 +70,6 @@ struct rxkad_stats rxkad_stats;
 #ifdef AFS_PTHREAD_ENV
 /* Pthread initialisation */
 static pthread_once_t rxkad_once_init = PTHREAD_ONCE_INIT;
-extern pthread_mutex_t rxkad_client_uid_mutex;
 extern pthread_mutex_t rxkad_random_mutex;
 
 static void
@@ -83,7 +82,6 @@ rxkad_global_stats_init(void)
 
 static void
 rxkad_InitPthread(void) {
-    MUTEX_INIT(&rxkad_client_uid_mutex, "uid", MUTEX_DEFAULT, 0);
     MUTEX_INIT(&rxkad_random_mutex, "rxkad random", MUTEX_DEFAULT, 0);
 
     rxkad_global_stats_init();
@@ -356,7 +354,6 @@ rxkad_NewConnection(struct rx_securityClass *aobj,
        if (!(tcp->type & rxkad_client))
            return RXKADINCONSISTENCY;
        rxkad_SetLevel(aconn, tcp->level);      /* set header and trailer sizes */
-       rxkad_AllocCID(aobj, aconn);    /* CHANGES cid AND epoch!!!! */
        rxkad_DeriveXORInfo(aconn, (fc_KeySchedule *)tcp->keysched, (char *)tcp->ivec, (char *)data->preSeq);
        INC_RXKAD_STATS(connections[rxkad_LevelIndex(tcp->level)]);
     }
index d514e20fab5dfce20aaddee696d2a8bce8064730..03ddb388823c67d524128a1cb82b8dc930096795 100644 (file)
@@ -26,6 +26,7 @@ EXEOBJS =\
 EXELIBS =\
        $(DESTDIR)\lib\afsrxkad.lib \
        $(DESTDIR)\lib\afsrx.lib \
+       $(DESTDIR)\lib\afshcrypto.lib \
        $(DESTDIR)\lib\afsdes.lib \
        $(DESTDIR)\lib\afslwp.lib \
        $(DESTDIR)\lib\afs\afscmd.lib \
index 33d5c8949a1d59404f1a0ea44797a2897b9a2b44..042050879b40b83d0d3160f8b39e7a736744e5bc 100644 (file)
@@ -20,6 +20,7 @@ LIBS=\
        ${TOP_LIBDIR}/librxkad.a \
        ${TOP_LIBDIR}/libsys.a \
        ${TOP_LIBDIR}/librx.a \
+       ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${TOP_LIBDIR}/liblwp.a \
        ${TOP_LIBDIR}/util.a \
        $(TOP_LIBDIR)/libopr.a \
index 08a6ba04be16fbfeb9f98b3bf5396be2e48d1752..a380cfe655aa792e8d76556c303ea509b6cf9286 100644 (file)
@@ -28,7 +28,8 @@ INCLS=${TOP_INCDIR}/lwp.h ${TOP_INCDIR}/lock.h \
        ${TOP_INCDIR}/rx/rx.h ${TOP_INCDIR}/rx/xdr.h \
        ${TOP_INCDIR}/lock.h ubik.h ubik_int.h
 
-LIBS=${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libauth.a \
+LIBS=${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/libafshcrypto_lwp.a \
+       ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libauth.a \
        ${TOP_LIBDIR}/libafscom_err.a ${TOP_LIBDIR}/libcmd.a \
        ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/libauth.a \
        ${TOP_LIBDIR}/libafsutil.a ${TOP_LIBDIR}/libopr.a \
index d1ccf56fc36b9e2d47ba2f448a86ed9938324c58..4a1b14282cc2ed0af907cbf0ca92436fa75b0a9c 100644 (file)
@@ -131,6 +131,7 @@ UDBG_EXEOBJS =\
 UDBG_EXELIBS =\
        $(DESTDIR)\lib\afsubik.lib \
        $(DESTDIR)\lib\afsrx.lib \
+       $(DESTDIR)\lib\afshcrypto.lib \
        $(DESTDIR)\lib\afs\afsreg.lib \
        $(DESTDIR)\lib\afslwp.lib \
        $(DESTDIR)\lib\afs\afscom_err.lib \
index 20f4629608bdefa1078b5f77bf5eb63791418dc9..d0cabf65ae1296c7039b753a00e4dd6888ad064f 100644 (file)
@@ -57,6 +57,7 @@ CMLIBS=${TOP_LIBDIR}/libsys.a \
         ${TOP_LIBDIR}/libafscom_err.a \
         ${TOP_LIBDIR}/libcmd.a \
         ${TOP_LIBDIR}/librx.a \
+        ${TOP_LIBDIR}/libafshcrypto_lwp.a \
         ${TOP_LIBDIR}/libsys.a \
         ${TOP_LIBDIR}/liblwp.a \
         $(TOP_LIBDIR)/libopr.a \
index d875bc6ef96ce9833b040da7c236fa3ff2b33893..192dea4d904a0e76794faa4d8a6f4154311b4e15 100644 (file)
@@ -15,6 +15,7 @@ HELPER_SPLINT=@HELPER_SPLINT@
 
 LIBS=${TOP_LIBDIR}/libcmd.a vlib.a ${TOP_LIBDIR}/util.a \
        ${TOP_LIBDIR}/libdir.a ${TOP_LIBDIR}/librx.a \
+       ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libsys.a \
        ${TOP_LIBDIR}/libacl.a ${TOP_LIBDIR}/libopr.a
 
index 18455d00a2e715bf429e5e4c601253e28061dabc..a402ef89c05bbae24af0ce4b7b154f4923e28d4d 100644 (file)
@@ -54,6 +54,7 @@ VOLDUMP_LIBS = \
        ${TOP_LIBDIR}/libafscom_err.a \
        ${TOP_LIBDIR}/libdir.a \
        ${TOP_LIBDIR}/librx.a  \
+       ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${TOP_LIBDIR}/liblwp.a  \
        ${TOP_LIBDIR}/libsys.a  \
        ${TOP_LIBDIR}/libacl.a \
index f91b67e2714250c528bfecd8d92e0f5367cfbef9..fcd0a426a1a5fb41e2835af89ef088bbd615a4fc 100644 (file)
@@ -18,6 +18,7 @@ RPCINCLS=${TOP_INCDIR}/lwp.h ${TOP_INCDIR}/rx/rx.h
 LIBS=${TOP_LIBDIR}/libafsint.a \
        ${TOP_LIBDIR}/libcmd.a \
        ${TOP_LIBDIR}/librx.a \
+       ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${TOP_LIBDIR}/liblwp.a \
        ${TOP_LIBDIR}/libsys.a \
        ${TOP_LIBDIR}/libopr.a \
index 23d456a9daf7ff20f240635b69e9fcbb61c9827d..feee07d4987f5b76de855badd25da83430e5436d 100644 (file)
@@ -22,6 +22,7 @@ LIBS= \
        $(LIBDIR)\afs\afsint.lib \
        $(LIBDIR)\afs\afscmd.lib \
        $(LIBDIR)\afsrx.lib \
+       $(LIBDIR)\afshcrypto.lib \
        $(LIBDIR)\afslwp.lib \
        $(LIBDIR)\afs\afspioctl.lib \
        $(LIBDIR)\afs\afsutil.lib \