int AsymmCipher::decrypt(const byte* cipher, int cipherlen, byte* out, int numbytes) { Integer m; if (!decodeintarray(&m, 1, cipher, cipherlen)) { return 0; } rsadecrypt(key, &m); unsigned l = key[AsymmCipher::PRIV_P].ByteCount() + key[AsymmCipher::PRIV_Q].ByteCount() - 2; if (m.ByteCount() > l) { l = m.ByteCount(); } l -= numbytes; while (numbytes--) { out[numbytes] = m.GetByte(l++); } return 1; }
unsigned AsymmCipher::rawdecrypt(const byte* c, int cl, byte* buf, int buflen) { Integer m(c,cl); rsadecrypt(key,&m); int i = m.ByteCount(); if (i > buflen) return 0; while (i--) *buf++ = m.GetByte(i); return m.ByteCount(); }
int rsasign(RSApriv *key, DigestAlg *hash, uchar *digest, uint dlen, uchar *sig, uint siglen) { uchar asn1[64], *buf; int n, len, pad; mpint *m, *s; /* * Create ASN.1 */ n = mkasn1(asn1, hash, digest, dlen); /* * Create number to sign. */ len = (mpsignif(key->pub.n)+7)/8 - 1; if(len < n+2) { werrstr("rsa key too short"); return -1; } pad = len - (n+2); if(siglen < len) { werrstr("signature buffer too short"); return -1; } buf = malloc(len); if(buf == nil) return -1; buf[0] = 0x01; memset(buf+1, 0xFF, pad); buf[1+pad] = 0x00; memmove(buf+1+pad+1, asn1, n); m = betomp(buf, len, nil); free(buf); if(m == nil) return -1; /* * Sign it. */ s = rsadecrypt(key, m, nil); mpfree(m); if(s == nil) return -1; mptoberjust(s, sig, len+1); mpfree(s); return len+1; }
int AsymmCipher::decrypt(const byte* c, int cl, byte* out, int numbytes) { Integer m; if (!decodeintarray(&m,1,c,cl)) return 0; rsadecrypt(key,&m); unsigned l = key[AsymmCipher::PRIV_D].ByteCount()-2; if (m.ByteCount() > l) l = m.ByteCount(); l -= numbytes; while (numbytes--) out[numbytes] = m.GetByte(l++); return 1; }
unsigned AsymmCipher::rawdecrypt(const byte* cipher, int cipherlen, byte* buf, int buflen) { Integer m(cipher, cipherlen); rsadecrypt(key, &m); int i = m.ByteCount(); if (i > buflen) { return 0; } while (i--) { *buf++ = m.GetByte(i); } return m.ByteCount(); }
static void recv_ssh_cmsg_session_key(Conn *c, AuthRpc *rpc) { int i, id, n, serverkeylen, hostkeylen; mpint *a, *b; uchar *buf; Msg *m; RSApriv *ksmall, *kbig; m = recvmsg(c, SSH_CMSG_SESSION_KEY); id = getbyte(m); c->cipher = nil; for(i=0; i<c->nokcipher; i++) if(c->okcipher[i]->id == id) c->cipher = c->okcipher[i]; if(c->cipher == nil) sysfatal("invalid cipher selected"); if(memcmp(getbytes(m, COOKIELEN), c->cookie, COOKIELEN) != 0) sysfatal("bad cookie"); serverkeylen = mpsignif(c->serverkey->n); hostkeylen = mpsignif(c->hostkey->n); ksmall = kbig = nil; if(serverkeylen+128 <= hostkeylen){ ksmall = c->serverpriv; kbig = nil; }else if(hostkeylen+128 <= serverkeylen){ ksmall = nil; kbig = c->serverpriv; }else sysfatal("server session and host keys do not differ by at least 128 bits"); b = getmpint(m); debug(DBG_CRYPTO, "encrypted with kbig is %B\n", b); if(kbig){ a = rsadecrypt(kbig, b, nil); mpfree(b); b = a; }else b = rpcdecrypt(rpc, b); a = rsaunpad(b); mpfree(b); b = a; debug(DBG_CRYPTO, "encrypted with ksmall is %B\n", b); if(ksmall){ a = rsadecrypt(ksmall, b, nil); mpfree(b); b = a; }else b = rpcdecrypt(rpc, b); a = rsaunpad(b); mpfree(b); b = a; debug(DBG_CRYPTO, "munged is %B\n", b); n = (mpsignif(b)+7)/8; if(n > SESSKEYLEN) sysfatal("client sent short session key"); buf = emalloc(SESSKEYLEN); mptoberjust(b, buf, SESSKEYLEN); mpfree(b); for(i=0; i<SESSIDLEN; i++) buf[i] ^= c->sessid[i]; memmove(c->sesskey, buf, SESSKEYLEN); debug(DBG_CRYPTO, "unmunged is %.*H\n", SESSKEYLEN, buf); c->flags = getlong(m); free(m); }
static void* rsa_sign(mpint* m, void *key) { return rsadecrypt((RSApriv*)key, m, nil); }